OpenSSL& public key and private key & Certificate

莊子弘
6 min readMay 9, 2020

--

前言

最近的一個Sprint剛剛結束,因為剛好都在摸JWT的東西,所以稍微研究了一點密碼學跟數位簽證,決定留個紀錄順便分享一下。因為我沒有了解得很透徹,如果有錯希望大家能幫我指正一下。

觀念

公私鑰與憑證(Public Keys, Private Keys, and Certificates)

當執行授權的時候,SSL採用的技術是公鑰加密(public-key cryptography)。
公鑰加密是基於一組成對的金鑰,這對金鑰包含了公鑰與私鑰。而資料可以透過公鑰加密再由私鑰解密,反之也可以透過私鑰加密再由公鑰解密。
PS: 你沒看錯,雖然叫做公鑰加密,但其實包含了私鑰==

加密流程

這對金鑰的所有者可以把公鑰給任何人,但私鑰必須私自保管。而憑證就是公鑰配上一些組織資訊。比如常用的X.509就是一種憑證規格,裡面包含了資料區以及簽署區,資料區的內容有:

  • 憑證的所有人
  • 憑證的發行人
  • 憑證的有效期限
  • 公鑰本身

你可以透過憑證授權機構(Certificate Authority)來取得授權,當然你也可以自己做,那你就同時是憑證的發行人與所有人。

憑證的檔案格式

ASN.1:就是一種數據的編碼標準,這東西我目前也搞不太清楚。需要知道的是,他就是DER的所採用的編碼標準。

.der:一種二元編碼的檔案格式,憑證可以透過這種格式儲存,而且java支援直接讀DER檔,用byte[]讀進來之後再轉成PKCS8EncodedKeySpec物件。

.pem:一種DER透過Base64加密過後的檔案格式,因為是純文字檔的關係更方便網路傳輸,是相當方便使用的一種憑證檔案格式。檔案第一行與最後一行會標記採用哪一種PKCS,以下是幾個常見的範例:

RSA private key (PKCS#1)

-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----

RSA public key (PKCS#1)

-----BEGIN RSA PUBLIC KEY-----

-----END RSA PUBLIC KEY-----

RSA private key (PKCS#8, key 沒加密 )

-----BEGIN PRIVATE KEY----

-----END PRIVATE KEY------

RSA public key (PKCS#8)

-----BEGIN PUBLIC KEY----

-----END PUBLIC KEY-----

DER與PEM都是常見的憑證檔案格式,當然還有其他格式,這些格式都可以透過OpenSSL來互相轉換。

openssl rsa -in key.pem -outform der -out key.der

X.509

剛剛有提到X.509是public key certificate的規格,TLS/SSL使用它,TLS/SSL是HTTPS的基礎所以HTTPS也使用它。而所謂Public Key Certificates又被稱為Digital Certificate 或 Identity Certificate。當然他也符合剛才PKC的規範,是由一些身份訊息加上公鑰所組成的。

PKCS

上面有出現過的陌生名詞來解釋一下吧,在密碼學裡,PKCS代表的是”Public Key Cryptography Standards”。剛剛說到的X.509是PKC,跟現在說的PKCS並不一樣喔。
PKCS一共有15個編號,但我只挑1,8,12來講就好,剩下的你們自己研究。

PKCS#1:RSA Cryptography Standard,用來定義RSA格式的公私鑰,是最基本的格式。

PKCS#8:Private-Key Information Syntax Standard,用來定義Private Certificate Keypairs儲存(不僅限RSA)。

PKCS#12:定義了用來儲存Public Key Certificates(例如前面提到的X.509)的文件格式,注意我用了s,代表PKCS#12其實是一個KeyStore,可以儲存多個Public Key Certificate,可以被用做Java Key Store(JKS)。

指令

*注意:windows可以透過git bash來使用OpenSSL,超方便。

製作:

PKCS#1格式的RSA Private Key
openssl genrsa -out private-key.p1.pem 2048

PKCS#12格式的X.509 certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
如果不想要有密碼保護就加-nodes。
-newkey rsa:4096:建立一把新的4096bits 的RSA KEY。
-keyout key.pem:輸出一把私鑰叫作key.pem
-out cert.pem:輸出憑證檔叫作cert.pem
-days 365:憑證有效期限365天

轉換:

PKCS #1 -> Unencrypted PKCS #8
openssl pkcs8 -topk8 -in private-key.p1.pem -out private-key.p8.pem -nocrypt

PKCS #8 -> PKCS #1
openssl rsa -in private-key.p8.pem -out private-key.p1.pem

從私鑰或憑證中提取公鑰:

提取X.509格式RSA Public Key
openssl rsa -in private-key.pem -pubout -out public-key.x509.pem

提取PKCS #1格式RSA Public Key
openssl rsa -in private-key.pem -out public-key.p1.pem -RSAPublicKey_out

從X.509憑證提取
openssl x509 -in cert.pem -pubkey -noout > public-key.x509.pem

如果對你有點幫助就幫我拍個手讓我知道吧,按住的話可以連續拍喔!

參考資料:
https://www.openssl.org/
https://docs.oracle.com/cd/E19509-01/820-3503/ggbgc/index.html
https://www.feistyduck.com/library/openssl-cookbook/online/ch-openssl.html
https://chanjarster.github.io/post/x509-pkcs-file-formats/
https://blog.cssuen.tw/create-a-self-signed-certificate-using-openssl-240c7b0579d3

--

--

莊子弘
莊子弘

Written by 莊子弘

文字工作者,不過周一到週五寫的都是程式碼。閒暇時間會分享一些心得,包含技術文章或影集書籍觀後感。

No responses yet