├── .gitignore
├── 身份基加密IBE.pdf
├── .idea
├── .gitignore
├── vcs.xml
├── modules.xml
├── misc.xml
└── libraries
│ └── lib.xml
├── data
├── msk.properties
├── sk.properties
├── ct.properties
└── pk.properties
├── lib
├── jpbc-api-2.0.0 2.jar
└── jpbc-plaf-2.0.0 2.jar
├── a.properties
├── IBE.iml
├── README.md
└── src
├── JPBCDemo.java
└── IBE.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project exclude paths
2 | /out/
--------------------------------------------------------------------------------
/身份基加密IBE.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hjlpb/IBE/HEAD/身份基加密IBE.pdf
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/data/msk.properties:
--------------------------------------------------------------------------------
1 | #Sun Jan 02 12:35:06 CST 2022
2 | x=WQRRYapCqPwqOG3Li+OYFuDkT7M\=
3 |
--------------------------------------------------------------------------------
/lib/jpbc-api-2.0.0 2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hjlpb/IBE/HEAD/lib/jpbc-api-2.0.0 2.jar
--------------------------------------------------------------------------------
/lib/jpbc-plaf-2.0.0 2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hjlpb/IBE/HEAD/lib/jpbc-plaf-2.0.0 2.jar
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/data/sk.properties:
--------------------------------------------------------------------------------
1 | #Sun Jan 02 12:35:06 CST 2022
2 | sk=Ltnr/83vDDeyBGZHcSYS34M6fBPY5ZS5szIkbf5nbkdfFUCLfN1O5wQBi9kEixr6GSu3+LXbQUPSc4soI+kC2guCkHpeWwzgmazuvMu4LYEjEAeGHcaI1G8/S+bcpGxuOP95eHPtfWy3etvjrsQ6e7PUtO7Nyq9TxuD7DVS73V0\=
3 |
--------------------------------------------------------------------------------
/data/ct.properties:
--------------------------------------------------------------------------------
1 | #Sun Jan 02 12:35:06 CST 2022
2 | C1=poUrHFWTpUZ5xj1qaaMFduKz7hBfdFglEtcGUKasI/DrtsjLbk5yFvWmAJjxBN+WPgmWDiOmIOI82zXwl8fEJQKiqLKOvXxXefmk9MIbq95xT7cH8Jve0oSoIC8V9PvLs90/HoD9fIwAmjyBLehWarft5TJeUNsZ41YxJGYOOdM\=
3 | C2=H0AsGyX22S2s6Q\=\=
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/libraries/lib.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/a.properties:
--------------------------------------------------------------------------------
1 | type a
2 | q 8780710799663312522437781984754049815806883199414208211028653399266475630880222957078625179422662221423155858769582317459277713367317481324925129998224791
3 | h 12016012264891146079388821366740534204802954401251311822919615131047207289359704531102844802183906537786776
4 | r 730750818665451621361119245571504901405976559617
5 | exp2 159
6 | exp1 107
7 | sign1 1
8 | sign0 1
9 |
--------------------------------------------------------------------------------
/data/pk.properties:
--------------------------------------------------------------------------------
1 | #Sun Jan 02 12:35:06 CST 2022
2 | gx=oDhNdr+y2M+2iX1ZNH7t4lUAz8pyWpSrTCK2EShcf4wpwC8Lm1jggsO9tpZs3BwGVfl4x9qur7C2z9VtkYEV353zdAT396TIPPF/1vU6bF+FOJCKdzI1D+eTwWVSZP87xAr6cfnWFfwat2DVZxQp+qtGPnpO8FK21EWw++lNeAc\=
3 | g=eFeLVjqZ0beuz5MCdEKtbWHETw7gTOlVoj1OaO7JDllAb3vogy+o05lYa0HEvl4E6e++UvB/n/NYKbrKW4D7JU+bnpqMg/+nYpinnZn009inycaGihhyQjtywbZ+9BlO07vnuLc6mQqv8x9IW0Jo24J7lpDMWK9Ahb4uexZpD9U\=
4 |
--------------------------------------------------------------------------------
/IBE.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 身份基加密 (Identity based Encryption)算法
2 |
3 | 论文 [Identity-Based Encryption from the Weil Pairing](https://crypto.stanford.edu/~dabo/papers/bfibe.pdf)
4 |
5 | ## Setup
6 |
7 | 1. 生成pairing相关公共参数 $$
8 | 2. 选取随机数$x\in Z_r$ 作为系统主密钥$msk$
9 | 3. 选取随机元素$g\in G_1$作为生成元,计算公共参数$g^x$。因此,有系统公钥$pk=$
10 | 4. 选取公共哈希函数 $H_1:\{0,1\}^*\rightarrow G_1^*$,$H_2:G_T \rightarrow \{0,1\}^n$
11 |
12 | ## KeyGen
13 |
14 | 1. 给定用户身份 $ID\in \{0,1\}^*$,将其映射为群$G_1$上的元素。即计算 $Q_{ID}=H_1(ID)$
15 | 2. 由系统主密钥$x$计算此$ID$对应的私钥为$sk=Q_{ID}^x$
16 |
17 | ## Encrypt
18 |
19 | 1. 针对目标用户身份$ID\in \{0,1\}^*$,计算 $Q_{ID}=H_1(ID)$
20 | 2. 选取随机数$r\in Z_r$,计算密文组件$C_1=g^r$
21 | 3. 计算$g_{ID}=e(Q_{ID},g^x)^r$
22 | 4. 计算密文组件$C_2=M \oplus H_2(g_{ID})$,其中$M \in \{0,1\}^n$是明文数据
23 | 5. 最终的密文为$$
24 |
25 | ## Decrypt
26 |
27 | 1. 解密的关键在于恢复$g_{ID}$
28 | 2. $e(sk,C_1)=e(Q_{ID}^x,g^r)=e(Q_{ID},g)^{xr}=g_{ID}$
29 | 3. 恢复明文 $M=C_2 \oplus H_2(e(sk,C_1))$
30 |
31 |
32 |
33 | # 代码实现
34 |
35 |
36 |
37 | # 注意事项
38 |
39 | 1. 选择用Properties保存是因为支持键值读取,比如密文可能包含多个组件,方便分别读取每个组件。
40 | 2. SetProperties的第二个参数必须为String类型,对于Zr群元素x可以调用`x.toBigInteger().toString()`
41 |
42 |
--------------------------------------------------------------------------------
/src/JPBCDemo.java:
--------------------------------------------------------------------------------
1 | import it.unisa.dia.gas.jpbc.Element;
2 | import it.unisa.dia.gas.jpbc.Field;
3 | import it.unisa.dia.gas.jpbc.Pairing;
4 | import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
5 |
6 |
7 | public class JPBCDemo {
8 | public static void main(String[] args) {
9 | // 一、基于特定椭圆曲线类型生成Pairing实例
10 | // 1.从文件导入椭圆曲线参数
11 | Pairing bp = PairingFactory.getPairing("a.properties");
12 |
13 | // 2.自定义曲线参数
14 | // int rBits = 160;
15 | // int qBits = 512;
16 | // TypeACurveGenerator pg = new TypeACurveGenerator(rBits, qBits);
17 | // PairingParameters pp = pg.generate();
18 | // Pairing bp = PairingFactory.getPairing(pp);
19 |
20 | // 二、选择群上的元素
21 | Field G1 = bp.getG1();
22 | Field Zr = bp.getZr();
23 | Element g = G1.newRandomElement().getImmutable();
24 | Element a = Zr.newRandomElement().getImmutable();
25 | Element b = Zr.newRandomElement().getImmutable();
26 |
27 | // 三、计算等式左半部分
28 | Element ga = g.powZn(a);
29 | Element gb = g.powZn(b);
30 | Element egg_ab = bp.pairing(ga,gb);
31 |
32 | // 四、计算等式右半部分
33 | Element egg = bp.pairing(g,g).getImmutable();
34 | Element ab = a.mul(b);
35 | Element egg_ab_p = egg.powZn(ab);
36 |
37 | if (egg_ab.isEqual(egg_ab_p)) {
38 | System.out.println("yes");
39 | }
40 | else {
41 | System.out.println("No");
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/IBE.java:
--------------------------------------------------------------------------------
1 | import it.unisa.dia.gas.jpbc.Element;
2 | import it.unisa.dia.gas.jpbc.Pairing;
3 | import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
4 |
5 | import java.io.FileInputStream;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.security.MessageDigest;
9 | import java.security.NoSuchAlgorithmException;
10 | import java.util.Base64;
11 | import java.util.Properties;
12 |
13 | public class IBE {
14 |
15 | public static void setup(String pairingParametersFileName, String pkFileName, String mskFileName) {
16 | Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
17 |
18 | Element x = bp.getZr().newRandomElement().getImmutable();
19 | Properties mskProp = new Properties();
20 | //mskProp.setProperty("x", x.toBigInteger().toString()); //x有toBigInteger方法,因此可以用这种方式,但g不能
21 | //后面对写的元素统一采用如下方法:首先将元素转为字节数组,然后进行Base64编码为可读字符串
22 | mskProp.setProperty("x", Base64.getEncoder().encodeToString(x.toBytes()));
23 | storePropToFile(mskProp, mskFileName);
24 |
25 | Element g = bp.getG1().newRandomElement().getImmutable();
26 | Element gx = g.powZn(x).getImmutable();
27 | Properties pkProp = new Properties();
28 | //pkProp.setProperty("g", new String(g.toBytes())); //可以用这种方式将g转换为字符串后写入,但文件中显示乱码
29 | //为了避免乱码问题,采用Base64编码方式
30 | pkProp.setProperty("g", Base64.getEncoder().encodeToString(g.toBytes()));
31 | pkProp.setProperty("gx", Base64.getEncoder().encodeToString(gx.toBytes()));
32 | storePropToFile(pkProp, pkFileName);
33 | }
34 |
35 | public static void keygen(String pairingParametersFileName, String id, String mskFileName, String skFileName) throws NoSuchAlgorithmException {
36 | Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
37 |
38 | byte[] idHash = sha1(id);
39 | Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();
40 |
41 | Properties mskProp = loadPropFromFile(mskFileName);
42 | String xString = mskProp.getProperty("x");
43 | // Element x = bp.getZr().newElement(new BigInteger(xString)); //对应于前面的x.toBigInteger().toString()方式
44 | Element x = bp.getZr().newElementFromBytes(Base64.getDecoder().decode(xString)).getImmutable(); //Base64编码后对应的恢复元素的方法
45 |
46 | Element sk = QID.powZn(x).getImmutable();
47 | Properties skProp = new Properties();
48 | skProp.setProperty("sk", Base64.getEncoder().encodeToString(sk.toBytes()));
49 | storePropToFile(skProp, skFileName);
50 | }
51 |
52 | public static void encrypt(String pairingParametersFileName, String message, String id, String pkFileName, String ctFileName) throws NoSuchAlgorithmException {
53 | Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
54 |
55 | byte[] idHash = sha1(id);
56 | Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();
57 |
58 | Properties pkProp = loadPropFromFile(pkFileName);
59 | String gString = pkProp.getProperty("g");
60 | Element g = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(gString)).getImmutable();
61 | String gxString = pkProp.getProperty("gx");
62 | Element gx = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(gxString)).getImmutable();
63 |
64 | Element r = bp.getZr().newRandomElement().getImmutable();
65 | Element C1 = g.powZn(r).getImmutable();
66 |
67 | Element gID = bp.pairing(QID, gx).powZn(r).getImmutable();
68 |
69 | String gIDString = new String(gID.toBytes());
70 | byte[] HgID = sha1(gIDString);
71 | byte[] messageByte = message.getBytes();
72 |
73 | byte[] C2 = new byte[messageByte.length];
74 | //假设m明文字节长度n小于HgID的长度20,取HgID的前n个字节进行异或
75 | for (int i = 0; i < messageByte.length; i++){
76 | C2[i] = (byte)(messageByte[i] ^ HgID[i]);
77 | }
78 |
79 | Properties ctProp = new Properties();
80 | ctProp.setProperty("C1", Base64.getEncoder().encodeToString(C1.toBytes()));
81 | ctProp.setProperty("C2", Base64.getEncoder().encodeToString(C2));
82 | storePropToFile(ctProp, ctFileName);
83 | }
84 |
85 | public static String decrypt(String pairingParametersFileName, String ctFileName, String pkFileName, String skFileName) throws NoSuchAlgorithmException {
86 | Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
87 |
88 | Properties skProp = loadPropFromFile(skFileName);
89 | String skString = skProp.getProperty("sk");
90 | Element sk = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(skString)).getImmutable();
91 |
92 | Properties ctProp = loadPropFromFile(ctFileName);
93 | String C1String = ctProp.getProperty("C1");
94 | Element C1 = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(C1String)).getImmutable();
95 | String C2String = ctProp.getProperty("C2");
96 | byte[] C2 = Base64.getDecoder().decode(C2String);
97 |
98 | Element gID = bp.pairing(sk, C1).getImmutable();
99 |
100 | String gIDString = new String(gID.toBytes());
101 | byte[] HgID = sha1(gIDString);
102 | byte[] res = new byte[C2.length];
103 | for (int i = 0; i < C2.length; i++){
104 | res[i] = (byte)(C2[i] ^ HgID[i]);
105 | }
106 | return new String(res);
107 | }
108 |
109 | public static void storePropToFile(Properties prop, String fileName){
110 | try(FileOutputStream out = new FileOutputStream(fileName)){
111 | prop.store(out, null);
112 | }
113 | catch (IOException e) {
114 | e.printStackTrace();
115 | System.out.println(fileName + " save failed!");
116 | System.exit(-1);
117 | }
118 | }
119 |
120 | public static Properties loadPropFromFile(String fileName) {
121 | Properties prop = new Properties();
122 | try (FileInputStream in = new FileInputStream(fileName)){
123 | prop.load(in);
124 | }
125 | catch (IOException e){
126 | e.printStackTrace();
127 | System.out.println(fileName + " load failed!");
128 | System.exit(-1);
129 | }
130 | return prop;
131 | }
132 |
133 | public static byte[] sha1(String content) throws NoSuchAlgorithmException {
134 | MessageDigest instance = MessageDigest.getInstance("SHA-1");
135 | instance.update(content.getBytes());
136 | return instance.digest();
137 | }
138 |
139 | public static void main(String[] args) throws Exception {
140 |
141 | String idBob = "bob@example.com";
142 | String idAlice = "alice@example.com";
143 | String message = "i hate you";
144 |
145 | String dir = "data/";
146 | String pairingParametersFileName = "a.properties";
147 | String pkFileName = dir + "pk.properties";
148 | String mskFileName = dir + "msk.properties";
149 | String skFileName = dir + "sk.properties";
150 | String ctFileName = dir + "ct.properties";
151 |
152 | setup(pairingParametersFileName, pkFileName, mskFileName);
153 |
154 | keygen(pairingParametersFileName, idBob, mskFileName, skFileName);
155 |
156 | encrypt(pairingParametersFileName, message, idBob, pkFileName, ctFileName);
157 |
158 | String res = decrypt(pairingParametersFileName, ctFileName, pkFileName, skFileName);
159 |
160 | System.out.println(res);
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------