JPBC简介
JPBC库是ABE加密以及椭圆曲线加密等常用的加密库。下载地址:http://gas.dia.unisa.it/projects/jpbc/index.html#.VTDrLSOl_Cw
1. 主要参数
a. 主要使用的椭圆曲线为TypeA型素数阶椭圆曲线,y² = x³ + x 参数如下:
public static String curveParams = "type a\n"
+ "q 87807107996633125224377819847540498158068831994142082"
+ "1102865339926647563088022295707862517942266222142315585"
+ "8769582317459277713367317481324925129998224791\n"
+ "h 12016012264891146079388821366740534204802954401251311"
+ "822919615131047207289359704531102844802183906537786776\n"
+ "r 730750818665451621361119245571504901405976559617\n"
+ "exp2 159\n" + "exp1 107\n" + "sign1 1\n" + "sign0 1\n";
TypeA1型为合数阶椭圆曲线,使用较少。
b.一般随机选择元素为从G1,G2,Gt以及Zp域选择,具体选择如下。
public Cpabe(String param){
this.pp = new PP();
this.mk = new MK();
PairingParameters params = new PropertiesParameters().load(new ByteArrayInputStream(param.getBytes()));
this.pp.p = PairingFactory.getPairing(params);
this.pp.g = this.pp.p.getG1().newRandomElement();//从G1域随机选取元素
//构造主密钥参数
this.mk.beta = this.pp.p.getZr().newRandomElement();
this.mk.g_alpha = this.pp.g.duplicate().powZn(this.pp.p.getZr().newRandomElement());
//构造公钥参数
this.pp.h = this.pp.g.duplicate().powZn(this.mk.beta);
this.pp.y = this.pp.p.pairing(this.pp.g, this.mk.g_alpha);//双线性配对操作
}
c. JPBC库的基本元素为Element,有newElement方法,可以从byte构造Element元素。
2. 双线性配对
双线性配对基于DBDH假设,在密码学有很广泛的应用,与基于离散对数难解性的指数运算加密相比,具有更高的效率。在我的实验过程中,双线性配对操作为1ms,进行一次底数为1024为G1域上的元素,指数为160为Zp域的指数运算用时为13ms左右,双线性配对效率更高。
双线性配对操作主要代码
this.pp.y = this.pp.p.pairing(this.pp.g, this.mk.g_alpha);//双线性配对操作,通过pairing来进行
在ABE中,一般设定G1域和G2域为相等的域,将G1域和G2域的元素映射到Gt域。
3. ECC加密
ECC安全基础为一般群模型,即在计算K=kG过程中,知道k和G很容易计算K,但是在知道K的情况下很难得到k。(这一小节使用的椭圆曲线为y² = x³ + x)
椭圆曲线加密一般使用的为GF§域上的安全椭圆曲线y² = x³ + ax + b,设定好椭圆曲线参数,直接进行运算
现在我们描述一个利用椭圆曲线进行加密通信的过程:
1、ALice选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G,G是系统公开参数
在设定好安全椭圆曲线的前提下,随机选取元素作为生成元即可。
Element G = cpabe.pp.p.getGT().newRandomElement(); //基点
2、Alice选择一个私有密钥k,并生成公开密钥K=kG。
这里为使用大整数作为私钥
Random random1=new Random();
BigInteger SK1= new BigInteger(160, random1);//大整数作为私钥1
//Element SK1 = cpabe.pp.p.getZr().newRandomElement(); //以Zp域随机元素作为私钥
//System.out.println(SK1);
//Date d1 = new Date();
Element PK1=G.duplicate().mul(SK1);//公钥1
3、Alice将Ep(a,b)和点K,G传给用户B。公开参数
4、Bob接到信息后 ,将待传输的明文m进行加密。这里m为随机选取的一个Element
Element encRc1 = m.duplicate().add(PK1.duplicate.mu.(r));//加密
Element encRc2 = G.duplicate().mul(r);
5、Bob将encRc1,encRc2传给用户A。
6、用户A接到信息后,计算encRc1-kencRc2,结果就是点m。
因为encRc1-kencRc2=m+rK-k(rG)=m+rK-r(kG)=m 。
4. 注意事项
**在所有的代码过程中需要注意Element.duplicate()方法**
如上图所示,可以看到无论是乘法运算,还是指数运算,最终结果均为同一点。
如果加入Element.duplicate()方法,则结果为正确结果。这是因为Element本身的因素,加入duplicate()方法之后,相当于对Element本身加入一个复制,在计算时不会覆盖本身。