SSL/TLS證書格式解釋以及轉換cmd
X.690,它是ITU-T標準,規定了幾種ASN.1編碼格式:
Basic Encoding Rules (BER)
Canonical Encoding Rules (CER)
Distinguished Encoding Rules (DER)
一、名詞解釋
1、.der (Distinguished Encoding Rules)區分編碼規則
DER 是ASN.1 眾多編碼方案中的一個。DER 是 BER 的子集,對數據產生一個唯一的序列化表示。(其實是二進制編碼)
DER 格式的證書是二進制形式,存儲在以 .der 和 .cer 為擴展名的文件中。這些證書大部分使用在基于java的web服務器上。
而一般 PEM 文件使用的是 base64 進行編碼,所以可以把 DER 編碼的文件轉換成 PEM 文件。
2、.pem (Privacy-Enhanced Mail)隱私增強郵件
PEM 是一種容器格式,可以將服務端證書(server certificate),中間證書(intermediate certificate),公鑰(public key),私鑰(private key)包含在一個文件中。用于存儲和發送加密密鑰,證書和其他數據。可能僅包含公鑰證書,也可以包含完整的證書鏈(包括公玥,私鑰,和根證書)。
服務端證書和中間證書也可以分別存放在 .crt 和 .cer 兩個文件中。私鑰可以單獨在一個 .key 文件中。
PEM 格式則使用 base64 編碼二進制數據,所以你可以用文本編輯器打開它,例如notepad,微軟的word等等。
PEM文件的文件格式:
-----BEGIN (label)-----
/* data */
-----END (label)-----
label 決定了被編碼消息的類型,通常這些類型有如下一些:
"CERTIFICATE", "CERTIFICATE REQUEST", "PRIVATE KEY", "ENCRYPTED PRIVATE KEY" and "X509 CRL".
---- BEGIN CERTIFICATE----
/* 證書 */
----END CERTIFICATE----
---- BEGIN RSA PRIVATE KEY-----
/* 私鑰 */
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
/* CSR */
-----END CERTIFICATE REQUEST-----
......
PEM 格式的數據通常存儲在以 .pem, .cer, .crt(證書) 或者 .key(公鑰或私鑰) 為后綴的文件中。
3、.key
.key 其實就是一個 PEM 格式只包含 公鑰或私玥 的文件,.key 作為文件名只是作為一個明顯的別名。
4、.csr (certificate signing request )證書簽名請求
.csr 是證書請求文件,是由 RFC 2986定義的PKCS10格式,包含部分/全部的請求證書的信息,比如,主題, 機構,國家等,并且包含了請求證書的公玥,這些被CA中心簽名后返回一張證書。返回的證書是公鑰證書(只包含公玥不含私鑰)。
證書簽名請求是申請人向證書頒發機構發送的一條消息,用于申請數字身份證書。
有 CSR 必定有 KEY,是成對的,CSR 最終變成為證書 crt,和私鑰 key 配對使用。證書下發后,CSR 就沒有用了,只是在交時候需要。
5、X.509
Public-Key Infrastructure (X.509) (pkix)
在密碼學中,X.509 公鑰證書格式的標準,也應用于許多Internet協議,包括TLS/SSL,它是HTTPS的基礎。
一個X.509證書包含一個公鑰和一個標識(主機名、組織或個人),由證書頒發機構簽名或自簽名。
X.509 還定義了證書撤銷列表,這是一種分發被簽名機構認為無效的證書信息的方法,以及認證路徑驗證算法,該算法允許證書由中間CA證書簽名,而中間CA證書又由其他證書簽名,最終到達信任錨。
X.509 DER 編碼(ASCII)的后綴是: .DER .CER .CRT
X.509 PAM 編碼(Base64)的后綴是: .PEM .CER .CRT
.cer/.crt是用于存放證書,它是2進制形式存放的,不含私鑰。
.pem跟crt/cer的區別是它以Ascii來表示。
6、PKCS (Public Key Cryptography Standards)(公鑰密碼學標準)
常見的有PKCS#7,PKCS#10,PKCS#12,其他的格式忽略吧
6.1、PKCS#7:
Cryptographic Message Syntax Standard
加密消息語法標準。
擴展名:.p7b .p7c .spc
使用 base64 編碼,用于在PKI下簽名和/或加密消息,還用于證書分發(例如作為對PKCS #10消息的響應)。只有證書可以存儲在這種格式的文件中(例如作為對 “PKCS #10證書簽名請求標準” 消息的響應),私鑰則不可以。
p7r是CA對證書請求的回復,只用于導入。
p7b以樹狀展示證書鏈(certificate chain),同時也支持單個證書,不含私鑰。
P7B證書包含在BEGIN (label) END (label)之間:
-----BEGIN PKCS7-----
/* P7B證書 */
-----END PKCS7-----
6.2、PKCS #8:
Private-Key Information Syntax Standard
私鑰信息語法標準,用于攜帶私有證書密鑰對(加密或未加密)。
6.3、PKCS#10:
Certification Request Standard
證書簽名請求標準,發送給認證機構要求認證公鑰的消息的格式。
p10是證書請求
6.4、PKCS#12:
Personal Information Exchange Syntax Standard
個人信息交換語法標準。
擴展名:.pfx .p12,使用二進制編碼。
PKCS#12文件通常用來存儲 服務端證書,中間證書,私鑰,并使用基于密碼的對稱密鑰進行保護。PFX 是 PKCS#12的前身。
跟pem文件不同的是,它的內容是完全加密的,用openssl可以把其轉換成包含公鑰和私鑰的 .pem 文件。
命令: openssl pkcs12 -in file-to-convert.p12 -out converted-file.pem -nodes
這類證書主要使用在Windows平臺。
二、SSL Certificate (編碼)格式
SSL Certificate實際上就是X.509 Certificate。X.509使用名為 Abstract Syntax Notation One (ASN.1)的通用語言來描述certificate的數據結構。
X.509 certificate 有幾種不同的格式,例如 PEM,DER,PKCS#7 和 PKCS#12。 PEM和PKCS#7格式使用Base64 ASCII編碼,而DER和PKCS#12使用二進制編碼。
如下圖就展示了X.509證書的編碼方式和文件擴展名。

參考來源:
> https://blog.csdn.net/yetugeng/article/details/100629159
> https://blog.csdn.net/xkdlzy/article/details/113380587?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=1
三、證書格式間的轉換命令
1、參數說明:
-nodes:一直對私鑰不加密。
-noout:不打印參數編碼的版本信息。
-clcerts:僅僅輸出客戶端證書,不輸出CA證書。
-cacerts:僅僅輸出CA證書,不輸出客戶端證書。
-nocerts:不輸出任何證書。
-nokeys:不輸出任何私鑰信息值。
(參考來源:https://blog.free-tools.cn/archives/1171)
2、pfx提取 證書和秘鑰:
#2.1 .pfx 生成證書和秘鑰:(常用)
openssl pkcs12 -in server.pfx
-nodes -out prikey_and_ca_bundle.pem //生成PRIVATE KEY和完整證書鏈信息
-clcerts -nodes -out prikey_and_clcert.pem //生成PRIVATE KEY和客戶端證書信息
#輸出數據內容:
-----BEGIN CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
#2.2 生成PRIVATE KEY
-nocerts -nodes -out prikey.key
#輸出數據內容:
-----BEGIN PRIVATE KEY-----(同2.1)
#2.3 生成EN PRIVATE KEY
-nocerts -out en_prikey.key //輸入pfx密碼后,需要再輸入 PEM pass phrase
#輸出數據內容:
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.4 生成客戶端證書信息
-clcerts -nokeys -out clcert.crt
#輸出數據內容:
-----BEGIN CERTIFICATE-----(同2.1)
#2.5 生成EN PRIVATE KEY和客戶端證書信息
-clcerts -out clcert_and_en_prikey.pem
#輸出數據內容:
-----BEGIN CERTIFICATE-----(同2.1)
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.6 生成RSA PRIVATE KEY
openssl rsa -in en_prikey.key -out rsa_prikey.key //需要輸入 pass phrase
#輸出數據內容:
-----RSA PRIVATE KEY-----
#2.7 客戶端證書以 der 編碼
openssl x509 -outform der -in clcert.crt -out clcert_der.crt
#輸出數據內容:
二進制數據
PEM編碼的證書簽名請求文件: -----BEGIN CERTIFICATE REQUEST-----
3、合成 .pfx
思路:使用crt + key 用來生成pfx證書文件。
openssl pkcs12 -export -out server.pfx -inkey prikey.key -in ***.crt
openssl pkcs12 -export -out server.pfx -inkey public.key -in crt.crt //unable to load private key
openssl pkcs12 -export -out server.pfx -inkey pair.key -in cert.pem //success
openssl pkcs12 -export -out server.pfx -inkey private.key -in cert.pem //success
提示輸入 .key文件的密碼
提示輸入即將生成的 .pfx文件的密碼(需要輸入兩次)
若成功,會生成 server.pfx文件
4、另一種提取私鑰的方法,從公鑰對中提取:
從pfx證書中提取密鑰信息,并轉換為key格式(pfx使用pkcs12模式補足) 1、提取密鑰對(如果pfx證書已加密,會提示輸入密碼) openssl pkcs12 -in server.pfx -nocerts -nodes -out prikey.key BEGIN PRIVATE KEY //1,和 4 相同,但比 4 多一些 Attributes 2、從密鑰對提取公鑰 openssl -in prikey.key -pubout -out public.key BEGIN PUBLIC KEY //或者 //openssl rsa -in en_prikey.key -pubout -out public.key //兩者輸出一致 3、從密鑰對提取RSA私鑰 openssl rsa -in pair.key -out private_rsa.key BEGIN RSA PRIVATE KEY 4、因為RSA算法使用的是 pkcs8 模式補足,需要對提取的私鑰進一步處理得到最終私鑰 openssl pkcs8 -topk8 -inform PEM -in private_rsa.key -outform PEM -nocrypt -out private.key BEGIN PRIVATE KEY //4,和 1 相同
參考:
> https://blog.51cto.com/u_15288038/2985496
5、查看pfx的信息,一般會包括 [CERTIFICATE][ENCRYPTED PRIVATE KEY]
openssl pkcs12 -in xxx.pfx -info
6、從cer證書中提取公鑰信息
openssl x509 -in xxxx.cer -pubkey -out pub.key
//輸出
-----BEGIN PUBLIC KEY-----
****
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
***
-----END CERTIFICATE-----
7、查看服務器返回的證書鏈,加密協議,加密套件
openssl s_client -connect www.baidu.com:443 -showcerts
8、本地生成測試證書
openssl genrsa -out client.key 2048 openssl req -new -x509 -key client.key -out client.crt -days 365
9、生成自簽名證書
自簽名:
# 1.生成私鑰
$ openssl genrsa -out server.key 2048
# 2.生成 CSR (Certificate Signing Request)
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=域名orIP/emailAddress=test@123.com" -new -key server.key -out server.csr
# 3.生成自簽名證書
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
私有 CA 簽名:
# 1.創建 CA 私鑰
$ openssl genrsa -out ca.key 2048
# 2.生成 CA 的自簽名證書
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=Server CA/emailAddress=test@123.com" -new -x509 -days 3650 -key ca.key -out ca.crt
# 3.生成需要頒發證書的私鑰
$ openssl genrsa -out server.key 2048
# 4.生成要頒發證書的證書簽名請求,證書簽名請求當中的 Common Name 必須區別于 CA 的證書里面的 Common Name
$ openssl req -subj "/C=CN/ST=test/L=test/O=test/OU=test/CN=域名orIP/emailAddress=test@123.com" -new -key server.key -out server.csr
# 5.用 2 創建的 CA 證書給 4 生成的 簽名請求 進行簽名
$ openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
(參考地址:http://www.rzrgm.cn/happy-8090/articles/11830636.html)
從PFX提取到 cert.pem,private.key 兩個文件后,可以配置在Nginx里。
另外:
IOS證書: .cer格式,二進制編碼
Android證書: .crt格式,base64編碼
//TODO 待補充
(1)生成原始RSA私鑰文件 rsa_private_key.pem(原始私鑰)
openssl genrsa -out rsa_private_key.pem 2048
(2)將原始RSA私鑰轉換為pkcs8格式private_key.pem(私鑰)
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
(3)生成RSA公鑰 rsa_public_key.pem(公鑰)
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
curl -vv https://trade8.sctrade.com:10002 -I
curl -vvv https://trade8.sctrade.com:10002 -I

浙公網安備 33010602011771號