paillier同态加密算法库 如何生成 RSAPublicKey 和 RSAPrivateKey 并获得密钥字符串和公私钥文件

    科技2022-07-15  130

    paillier同态加密算法库地址:

    https://github.com/FISCO-BCOS/paillier-lib

     

    开发示例 

    // generate the key pair for encrypt and decrypt KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); RSAPublicKey pubKey = (RSAPublicKey)keypair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey)keypair.getPrivate(); // encrypt the first number with public key BigInteger i1 = BigInteger.valueOf(1000000); String c1 = PaillierCipher.encrypt(i1, pubKey); // encrypt the second number with same public key BigInteger i2 = BigInteger.valueOf(2012012012); String c2 = PaillierCipher.encrypt(i2, pubKey); // paillier add with numbers String c3 = PaillierCipher.ciphertextAdd(c1,c2); // decrypt the result BigInteger o3 = PaillierCipher.decrypt(c3, priKey);

     其中,生成并用于加密的公钥为:

    RSAPublicKey 类型

    生成并用于解密的私钥为: 

    RSAPrivateKey 类型

    但实际上使用 keypair 的 get 方法得到的公私密钥就是 security 库中常用的普通 PublicKey 和 PrivateKey ,只是进行了强制类型转换,相关操作可以直接参考。

     

    import java.security.*;

     

    获取公钥字符串

    可以使用如下方法:

    PaillierKeyPair.publicKeyToPem() KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey) keypair.getPrivate(); System.out.println("RSAPublicKey"); String pubstr = PaillierKeyPair.publicKeyToPem(pubKey); System.out.println(pubstr);

     结果:

     

    获取私钥字符串

    可以使用如下方法:

    PaillierKeyPair.privateKeyToPem() KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey) keypair.getPrivate(); System.out.println("RSAPrivateKey"); String pristr = PaillierKeyPair.privateKeyToPem(priKey); System.out.println(pristr);

    结果:

     

    将公钥和私钥字符串保存成文件

    类似于直接将String类型写入文件,查了一下似乎公钥存储为 .pem 文件,私钥存储为 .key 文件。但实际上都类似于写到txt文档,可能后缀和编码方式会有些关联。

    PEM – Privacy Enhanced Mail,打开看文本格式,以”—–BEGIN。。。”开头, “—–END。。。”结尾,内容是BASE64编码。 查看PEM格式证书的信息:openssl x509 -in certificate。pem -text -noout Apache和*NIX服务器偏向于使用这种编码格式。 

    KEY – 通常用来存放一个公钥或者私钥,并非X。509证书,编码同样的,可能是PEM,也可能是DER。 查看KEY的办法:openssl rsa -in mykey。key -text -noout 如果是DER格式的话,同理应该这样了:openssl rsa -in mykey。key -text -noout -inform der 

    // 写入公钥文件 try { FileWriter fw = new FileWriter("pubKey.pem"); fw.write("");//清空原文件内容 fw.write(pubstr); fw.flush(); fw.close(); } catch (IOException e) { e.printStackTrace(); } // 写入私钥文件 try { FileWriter fw = new FileWriter("priKey.key"); fw.write("");//清空原文件内容 fw.write(pristr); fw.flush(); fw.close(); } catch (IOException e) { e.printStackTrace(); }

     

    如何从字符串恢复出公钥文件和私钥文件

    这里以 RSAPublicKey 和 RSAPrivateKey 为例,但其实 PublicKey 和 PrivateKey 也可以,去掉强制类型转换即可。 String cp_pub= "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuNbhJjGqD9cIlwNUAqos\n" + "Eh32yJD0lwgoTFbYIzk0QuDvt2MD2mOz1nOUPY72IV80/00Rdn/nIMIiHRvUyptn\n" + "cQIrwsGnhAlE02JNg3LkpAxzWbCZ8RAKFKMGtqFfS2XYEGZs1TLjR+2NSpUMDD9i\n" + "gWlpsa49ADDsA8WrjD6aqEba79RP4XvNypbdW47twf9kAiDtKFjJaioBWRplIWUC\n" + "qRQ9F6N+awnPxqgUpTxeNhEI12qRzryjZ4sAh3VPmRa3rTTCqa0UXbUVZVniiVPX\n" + "qDl/XPOLJJRQfjHwY1s/5f9Lq//OLWy8cd2naaWTF88rKY6PoAieZZH+fRxUbb47\n" + "WQIDAQAB\n" + "-----END PUBLIC KEY-----\n"; String cp_pri = "-----BEGIN PRIVATE KEY-----\n" + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC41uEmMaoP1wiX\n" + "A1QCqiwSHfbIkPSXCChMVtgjOTRC4O+3YwPaY7PWc5Q9jvYhXzT/TRF2f+cgwiId\n" + "G9TKm2dxAivCwaeECUTTYk2DcuSkDHNZsJnxEAoUowa2oV9LZdgQZmzVMuNH7Y1K\n" + "lQwMP2KBaWmxrj0AMOwDxauMPpqoRtrv1E/he83Klt1bju3B/2QCIO0oWMlqKgFZ\n" + "GmUhZQKpFD0Xo35rCc/GqBSlPF42EQjXapHOvKNniwCHdU+ZFretNMKprRRdtRVl\n" + "WeKJU9eoOX9c84sklFB+MfBjWz/l/0ur/84tbLxx3adppZMXzyspjo+gCJ5lkf59\n" + "HFRtvjtZAgMBAAECggEAVy+8Wei5P+l9OsYuHWepjA4oNujxBkCpyYB5SPwVo6o4\n" + "SHdi/ONkk7ZG6VaC0LD47aerogqoufH4Z2SWVc9B1rNgcugnnQdGOLM4vtU19g+N\n" + "ZXQA2Q1ow902MHUj3wu2A95cXaA4RthNei2d1jUbwNE5Mr9uNKXe3dSim294QgED\n" + "/MPo9n+21SXqExviAV5WegGFcOrFtlDmPaKimgP0y0VhpN3MkV+yxxH8hxc66zuz\n" + "H6hWHtX+96bDJ9relTYONRa6lFR3tAUpcacC4hDhwjm+4xiacUVaz8bH/JqGgECp\n" + "CyzsAqAzaa6m9jMYsqrQwIVH3ohLHFbn9Ql3Q/d1EQKBgQDuGzaZmXFYaVhzlsxe\n" + "WEdA6BBEQrBqbsBBNZKzRz/R/kXKlL/2wbqOdhwoP90MUzPh5RYULzORjfO2t9j/\n" + "urzoj3+VsSakCEzznAtm3RMyIv/9hEYqMYz275kn+4uiWxUaW886G4zghC7Py45R\n" + "FxcGXAvBy27la8YBWKZ2qSZdxQKBgQDGuuUqVyxovEYlY8DNuksl7ELdmH+++m5K\n" + "2KKMjleEZcngcY1ml7nmiXDr4cSRKOkKh83Fs8YjQH0JxloVL8JQzvHbBL1cMp48\n" + "+bUAUFtY0WzPGIFopuib46Hzw2PEYCHba8APCuy4OoytMZJ3yrZxT5wofMrd5Zk9\n" + "EPiTbm20hQKBgCSIClWApFJDP23kmhBzjOMZd71xWe3KdjbLCGn3KYSHdZ/COL2c\n" + "NYo79s/6FGkaruAerMeGAmx3kgfbpzB9LxSjR5jo6BvMpjnOHDW4/4P2uL3luHoq\n" + "xgzw79ehkWfkf5Vetqmcpn2f6iq5eWlZmI/COY+PLcGHSobUWh3kj91dAoGBALu7\n" + "Vj0XOJaANOuhPkOaFt9uPwRCyXrJ7GK8H2IUHUyvM3PZETC3aCAF+ix6jExsjykp\n" + "fROkbipjAzu2quaUxUW9GPBDm/Z6wszrPzdasdBHljhU9/q6ocaR1S4HiDm8bn9v\n" + "XHFZaqHmfXom+Cw9zPdhsyz0JlhUStxLKedsTCpZAoGBAOzyxJFrOyToMxBecA+G\n" + "FGdC6ZTURdlJV1VILsff8+yEMO+Zj6AJ1FS19Z/DTBJ3DuCm1R4icis6gj4wuN1/\n" + "0/QnPrw4mPQyRbWdUUNFcLYEpEgriQmlOegmNb3fTi32cgCy4Ry4GTEFseXuAntI\n" + "rSD9gLvPVbg7cPNP0zEdeuHa\n" + "-----END PRIVATE KEY-----\n"; RSAPublicKey cp_pubKey = (RSAPublicKey) PaillierKeyPair.pemToPublicKey(cp_pub); RSAPrivateKey cp_priKey = (RSAPrivateKey) PaillierKeyPair.pemToPrivateKey(cp_pri);

    字符串中的 \n 和 \r 实际上对加密解密没有影响。

    测试了加密解密没有问题,但产生的密文不同,因为防止破解在加密机制中加入了一定的随机性,同一密钥加密两次结果也不同,但解密后的内容是一致的。

    一段密文:

    0100B8D6E12631AA0FD70897035402AA2C121DF6C890F49708284C56D823393442E0EFB76303DA63B3D673943D8EF6215F34FF4D11767FE720C2221D1BD4CA9B6771022BC2C1A7840944D3624D8372E4A40C7359B099F1100A14A306B6A15F4B65D810666CD532E347ED8D4A950C0C3F62816969B1AE3D0030EC03C5AB8C3E9AA846DAEFD44FE17BCDCA96DD5B8EEDC1FF640220ED2858C96A2A01591A65216502A9143D17A37E6B09CFC6A814A53C5E361108D76A91CEBCA3678B0087754F9916B7AD34C2A9AD145DB5156559E28953D7A8397F5CF38B2494507E31F0635B3FE5FF4BABFFCE2D6CBC71DDA769A59317CF2B298E8FA0089E6591FE7D1C546DBE3B594CA0CBD0508E68EFD9CEC0D0C2CCA4D7630893C46CA9940BC33397B392136A7981699C8E560230592A7E646D3B4224BD4DF7B596F023A41B7EE8EEAB5AE4ABD87883DB596C4D72A795C046AC3F15DEFE85BF400C7A226E267EF3CD4150028FF21648CAA1AB95456472BD51580633F1BFD5DFADD1757A67986A6195B4D1F8A67691C2CD041A5928883EC0CA4B50FB9DE3E610DEE6AED8B41AE71649D9FB21BA88965D076A9DAFE97035E8EEEF0A6D023FA388C6824FE877D34DE3E18C977D279C63E1FF6307ABADDCCBB5DC04ADBE6F8E6C2745933661E1C13343D87E80B9DED59EC353021436602403F1FE83CBEBC81A42FB41063D578C0D3631AEB4E2E906BC2E0C0AB51ECA823D10C3FB5B67D563A5C0FC3263D75218A0C66C5518CA5FE35C6ED5B7CBB06EA91B02043C4B9CA44577DC0C6A28B988A84A1AFED8893295128E238BBD13404F9D6B6BA27C20E9DBEFB8DA56DEC33431742D69A0AA9241EBAF8200CC5BBD83834B7E663981115CD463642F659E8B108C6BB7B85DC4BE555F7088FD1AF4FB4A4BAA8801ECDEC41FBDBFD64DAFA2AA3A68B26A41B39B599B78F74B6900AB1F3B7225E8EC6D79AF0A5F22357FBC83777CE330C09C72DBFAF497C6F59B3E9EF1A3F2327AE6BCEA9498AC1F90BA1479688D956550BC1D53A1A72DA98F4042ACA5D5E66066DC53C900464873B95517098E6D86CD01D13F9834F4FE4E9D

     

    从 RSAPrivateKey 类型对象获取公钥字符串的另一种方式

    从 RSAPrivateKey 类型对象获取私钥字符串也可以使用此方法,参考 PublicKey 和 PrivateKey 的获取,即编码后将 base64 转为 string 类型即可。

    // 获取公钥字符串 String pub = Base64.encodeBase64String(pubKey.getEncoded()); System.out.println(pub); // 获取私钥字符串 String pri = Base64.encodeBase64String(priKey.getEncoded()); System.out.println(pri);

    注意:不是随便敲一串字母就可以作为密钥string使用的,需要用严格的代码生成公钥串和私钥串。

    这里使用 KeyPair 的 RSAPrivateKey 和 RSAPrivateKey 本质上是一串数字。

    KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey) keypair.getPrivate(); System.out.println(pubKey.toString()); System.out.println(priKey.toString());

    输出结果:

     

    参考:

    RSA加密解密,String转PublicKey、PrivateKey;附Base64.JAR: https://blog.csdn.net/qq_35605213/article/details/80591869

    RSA密钥的数据类型转换:由合法的string到PublicKey或PrivateKey: https://blog.csdn.net/xdy1120/article/details/98756747

    PEM_密钥对生成与读取方法: https://www.cnblogs.com/jpfss/p/10063007.html

    关于pem和key区别: https://www.trustauth.cn/wiki/12756.html

    RSA公钥文件(PEM)解析: https://blog.csdn.net/xuanshao_/article/details/51679824

    .pem和.pub与非后缀ssh凭证文件有什么区别? https://qastack.cn/superuser/527218/what-is-the-difference-between-the-pem-and-pub-and-non-suffixed-ssh-credentials-files

    SSL中,公钥,私钥,证书的后缀名都是些啥: https://www.zhihu.com/question/29620953

     

     

     

    Processed: 0.015, SQL: 8