ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

RSA算法---公钥密钥对生成方法

2020-05-22 17:57:28  阅读:287  来源: 互联网

标签:公钥 私钥 openssl RSA rsa pem 密钥 key


前言:

PEM是OpenSSL和许多其他SSL工具的标准格式,OpenSSL 使用PEM 文件格式存储证书和密钥。这种格式被设计用来安全的包含在ascii甚至富文本文档中,如电子邮件。这意味着您可以简单的复制和粘贴pem文件的内容到另一个文档中。

PEM文件是Base64编码的证书。PEM证书通常用于web服务器,因为他们可以通过一个简单的文本编辑器,很容易地转换成可读的数据。通常当一个PEM编码在文本编辑器中打开文件,它会包含不同的页眉和页脚。

-----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATEREQUEST-----

CSR(证书签名请求)

-----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATEKEY-----

私钥

-----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----

证书文件


PKCS #8: Private-Key Information Syntax(语法) Standard(标准)

OpenSSL:是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。

一、OpenSSL生成pem格式公私钥


1、生成RSA私钥

openssl genrsa -out rsa_private_key.pem 1024

该命令会生成1024位的私钥,运行,如下图:

 

生成私钥文件rsa_private_key.pem,内容如下:

 

用记事本方式打开它,可以看到-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾的字符串,这个就是原始的私钥。

 备注:若运行openssl.exe,会进入OpenSSL命令行界面,此时输入命令时,则无需再写openssl。

 

2、RSA私钥转换成PKCS8格式

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -out rsa_private_key_01.pem -nocrypt

打开生成的文件后可以看到,控制台打印出的内容,-----BEGIN PRIVATE KEY-----开头,-----END PRIVATE KEY-----结尾的字符串,这个就是PKCS#8格式的私钥。

 

3、生成RSA公钥

openssl rsa -in rsa_private_key.pem-pubout -out rsa_public_key.pem

运行,如下图:

 

 

生成公钥文件rsa_public_key.pem, 打开它,可以看到-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾的字符串,这个就是公钥。

 

4、Java使用pem文件内容,示例代码

1)私钥签名

a)获取私钥

//获取KeyFactory,指定RSA算法

KeyFactorykeyFactory = KeyFactory.getInstance("RSA");

//将BASE64编码的私钥字符串进行解码

BASE64Decoderdecoder = newBASE64Decoder();

byte[] encodeByte = decoder.decodeBuffer(priKey);

//将BASE64解码后的字节数组,构造成PKCS8EncodedKeySpec对象,生成私钥对象

PrivateKeyprivatekey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodeByte));

        

b)使用私钥,对数据进行签名

         //获取Signature实例,指定签名算法(本例使用SHA1WithRSA)

Signaturesignature = Signature.getInstance("SHA1WithRSA");

//加载私钥

signature.initSign(privatekey);

//更新待签名的数据

signature.update(plain.getBytes("UTF-8"));

//进行签名

byte[] signed = signature.sign();

//将加密后的字节数组,转换成BASE64编码的字符串,作为最终的签名数据

BASE64Encoderencoder = newBASE64Encoder();

return encoder.encode(signed);

 

2)公钥验签

a)获取公钥

//获取KeyFactory,指定RSA算法

KeyFactorykeyFactory = KeyFactory.getInstance("RSA");

   //将BASE64编码的公钥字符串进行解码

BASE64Decoderdecoder = newBASE64Decoder();

byte[] encodeByte = decoder.decodeBuffer(pubKey);

//将BASE64解码后的字节数组,构造成X509EncodedKeySpec对象,生成公钥对象

PublicKeypublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodeByte));

 

b)使用公钥,进行验签

//获取Signature实例,指定签名算法(与之前一致)

Signaturesignature = Signature.getInstance("SHA1WithRSA");

//加载公钥

signature.initVerify(publicKey);

//更新原数据

signature.update(plain.getBytes("UTF-8"));

//公钥验签(true-验签通过;false-验签失败)

BASE64Decoderdecoder = newBASE64Decoder();

returnsignature.verify(decoder.decodeBuffer(sign));     

备注:

验签时,签名数据需要先BASE64解码

附:遇到的问题:在RSA加解密验证时,使用私钥无法生成签名,报algid parse error, not a sequence错误
原因:私钥在使用前为pkcs1格式,而java在不引用第三方包的情况下无法直接使用pkcs1格式的秘钥,需要将其转化为pkcs8编码
解决方案:使用openssl(官网:https://www.openssl.org/source/)将私钥进行pkcs8编码,将秘钥文件拷贝到openssl安装目录中,打开cmd命令进入该目录,执行命令:
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -out rsa_private_key_01.pem -nocrypt
其中rsa_private_key.pem表示原私钥文件,rsa_private_key_01.pem表示pkcs8编码后的私钥文件。
注:目前网上还没找到java在不使用第三方jar包的情况下处理pkcs1格式私钥的解决方案。绝大多数都是使用openssl工具将秘钥文件处理为pkcs8编码后再进行操作。

标签:公钥,私钥,openssl,RSA,rsa,pem,密钥,key
来源: https://www.cnblogs.com/yeluowuti/p/12938605.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有