├── .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 | --------------------------------------------------------------------------------