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

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

猜你喜欢

转载自blog.csdn.net/Ximerr/article/details/108919674