转自 http://blog.csdn.net/qifuchenluo/article/details/45100851
前言
现在网上关于Java版的双线性对算法的实现的代码很少,我在前段时间想找下这方面的代码都找不到,结果只能自己摸索。经过一段时间的摸索,终于配置好了jPBC库并实现了一些代码。所以为了让大家学习双线性算法的实现时少走点弯路,想通过博客的形式将我前段时间的学习成果跟大家分享下,为处于研究双线对密码初级阶段,还不懂得如何用java实现算法的菜鸟们提供一篇技术性的博客。
正文
关于java配对库网址为http://gas.dia.unisa.it/projects/jpbc/index.html#.VTDrLSOl_Cw,在这个网址http://gas.dia.unisa.it/projects/jpbc/docs/pairing.html#.Vz2yzOyEAzB有基本函数的用法,只看这个网址,相信很多对于Pairing-Based Cryptography Library (JPBC)还没入门的同学肯定是看的云里雾里的,看着就烦,其实我当初就是这样的。大家先不用急,学习这个库也是一个循序渐进的过程。关于jPBC库的配置,推荐一篇博客http://blog.csdn.net/liuweiran900217/article/details/23414629,这个博客已经将jPBC的配置写的很详细了,我就不赘述了。JPBC库中函数的基本使用和一些简单的算法实现,现在还没有发现专门介绍java的PBC库的相关书籍,推荐一本李发根,吴威峰著的书——《基于配对的密码学》,这本书详细讲了PBC库中每个函数的使用,还有经典算法的代码实现,这本书是C语言版的,对照这本书来研究JPBC会相对轻松很多。
用JPBC实现的算法实例
BasicIdent的基于身份的加密体制是由Boneh和Franklin在《Identity-Based Encryption fromthe Weil Pairing》提出的,算法的加解密过程大家可以自行参考下这篇论文,过程还是比较简单的。
Ident接口
- package cn.edu.zjut.pbc;
-
-
- public interface Ident {
-
- void buildSystem();
-
- void extractSecretKey();
-
- void encrypt();
-
- void decrypt();
-
- }
这个类是核心类,包括初始化init
(),配对的对称性判断checkSymmetric(),系统建立buildSystem(),密钥提取extractSecretKey(),加密encrypt(),解密decrypt()。
- package cn.edu.zjut.pbc;
-
- import it.unisa.dia.gas.jpbc.*;
- import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
- import java.lang.reflect.Proxy;
- import java.util.Calendar;
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- public class BasicIdent2 implements Ident {
-
- private Element s, r, P, Ppub, Su, Qu, V, T1, T2;
- private Field G1, Zr;
- private Pairing pairing;
-
- public BasicIdent2() {
- init();
- }
-
-
-
-
- private void init() {
- pairing = PairingFactory.getPairing("a.properties");
- PairingFactory.getInstance().setUsePBCWhenPossible(true);
- checkSymmetric(pairing);
-
- Zr = pairing.getZr();
- r = Zr.newElement();
-
- G1 = pairing.getG1();
- Ppub = G1.newElement();
- Qu = G1.newElement();
- Su = G1.newElement();
- V = G1.newElement();
-
- Field GT = pairing.getGT();
- T1 = GT.newElement();
- T2 = GT.newElement();
- }
-
-
-
-
-
-
- private void checkSymmetric(Pairing pairing) {
- if (!pairing.isSymmetric()) {
- throw new RuntimeException("密钥不对称!");
- }
- }
-
- @Override
- public void buildSystem() {
- System.out.println("-------------------系统建立阶段----------------------");
- s = Zr.newRandomElement().getImmutable();
- P = G1.newRandomElement().getImmutable();
- Ppub = P.mulZn(s);
- System.out.println("P=" + P);
- System.out.println("s=" + s);
- System.out.println("Ppub=" + Ppub);
- }
-
- @Override
- public void extractSecretKey() {
- System.out.println("-------------------密钥提取阶段----------------------");
- Qu = pairing.getG1().newElement().setFromHash("IDu".getBytes(), 0, 3)
- .getImmutable();
- Su = Qu.mulZn(s).getImmutable();
- System.out.println("Qu=" + Qu);
- System.out.println("Su=" + Su);
- }
-
- @Override
- public void encrypt() {
- System.out.println("-------------------加密阶段----------------------");
- r = Zr.newRandomElement().getImmutable();
- V = P.mulZn(r);
- T1 = pairing.pairing(Ppub, Qu).getImmutable();
- T1 = T1.powZn(r).getImmutable();
- System.out.println("r=" + r);
- System.out.println("V=" + V);
- System.out.println("T1=e(Ppub,Qu)^r=" + T1);
- }
-
- @Override
- public void decrypt() {
- System.out.println("-------------------解密阶段----------------------");
- T2 = pairing.pairing(V, Su).getImmutable();
- System.out.println("e(V,Su)=" + T2);
- int byt = V.getLengthInBytes();
- System.out.println("文本长度" + (byt + 128));
- }
-
- public static void main(String[] args) {
- BasicIdent2 ident = new BasicIdent2();
-
- Ident identProxy = (Ident) Proxy.newProxyInstance(
- BasicIdent2.class.getClassLoader(),
- new Class[] { Ident.class }, new TimeCountProxyHandle(ident));
-
- identProxy.buildSystem();
- identProxy.extractSecretKey();
- identProxy.encrypt();
- identProxy.decrypt();
- }
-
- }
最后使用了动态代理(java自带的代理模式)用来统计各个阶段的耗时。
- package cn.edu.zjut.pbc;
-
-
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
-
-
-
-
-
-
- public class TimeCountProxyHandle implements InvocationHandler {
-
- private Object proxied;
-
- public TimeCountProxyHandle(Object obj) {
- proxied = obj;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- long begin = System.currentTimeMillis();
- Object result = method.invoke(proxied, args);
- long end = System.currentTimeMillis();
- System.out.println(method.getName() + "耗时:" + (end - begin) + "ms");
- return result;
- }
- }
运行结果展示
由于电脑配置的不同,运行耗时会有差异,大家对于这篇博客如有任何问题,欢迎在CSDN上与我讨论。