RSA算法---公鑰密鑰對生成方法


前言:

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編碼后再進行操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM