PEM_密鑰對生成與讀取方法


 PS:歡迎轉載,但請注明出處,謝謝配合。

前言:

PEMOpenSSL和許多其他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.pem1024

 

該命令會生成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 -nocrypt

 

可以看到,控制台打印出的內容,-----BEGIN PRIVATE KEY-----開頭,-----END PRIVATE KEY-----結尾的字符串,這個就是PKCS#8格式的私鑰。


備注:

使用該命令,將私鑰轉成PKCS#8格式,但原rsa_private_key.pem文件中的私鑰字符串並沒有任何變化。但控制台輸出的private key,跟rsa_private_key.pem文件中的private key,不一樣。若需使用PKCS8格式的私鑰,即控制台中顯示的私鑰,將其拷貝出來即可。


切記:

opensslpkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM nocrypt

“-”書寫正確,上述nocrypt,因為前面的不是英文的,導致nocrypt失效,所以還需要輸入密碼。需要輸入兩次密碼,運行,如下圖:


       可以看到,控制台打印出的內容,-----BEGIN ENCRYPTED PRIVATE KEY-----開頭,-----END ENCRYPTED PRIVATE KEY-----結尾的字符串,這個就是加了密的PKCS#8格式的私鑰。

       因為輸入了密碼,轉換后的字符串不一樣,會比加了-nocrypt的長一些,所以原來的程序解析不了該私鑰字符串,會出錯。

 

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解碼

 


免責聲明!

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



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