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 xx.pem //輸入pfx密碼 openssl pkcs12 -in server.pfx -clcerts -nodes -out cert_and_en_pri_key.pem //輸入pfx密碼 #輸出數據內容: -----BEGIN CERTIFICATE----- -----BEGIN PRIVATE KEY-----
#2.2 .pfx 生成 秘鑰(未加密的): openssl pkcs12 -in server.pfx -nocerts -nodes -out pri_key.pem //輸入pfx密碼 #輸出數據內容: -----BEGIN PRIVATE KEY-----(內容同2.1中的私鑰信息)
#2.3 .pfx 生成 加密秘鑰:
openssl pkcs12 -in server.pfx -nocerts -out encrypt_pri_key.pem //輸入pfx密碼后,需要再輸入 PEM pass phrase
#輸出數據內容:
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.4 .pfx 生成 客戶端證書:
openssl pkcs12 -in server.pfx -clcerts -nokeys -out cert.pem //輸入pfx密碼即可
#輸出數據內容:
-----BEGIN CERTIFICATE-----(內容同2.1中的證書信息)
#2.5 .pfx 生成 客戶端證書+加密秘鑰:
openssl pkcs12 -in server.pfx -clcerts -out cert_and_en_pri_key.pem //有證書和加密秘鑰
#輸出數據內容:
-----BEGIN CERTIFICATE-----(內容同2.1中的證書信息)
-----BEGIN ENCRYPTED PRIVATE KEY-----
#2.6 加密秘鑰 生成 RSA私鑰:
openssl rsa -in encrypt_pri_key.pem -out private.key //需要輸入 pass phrase
#輸出數據內容:
-----RSA PRIVATE KEY-----
#2.7 客戶端證書以 der 編碼生成 .crt 證書
openssl x509 -outform der -in cert.pem -out crt.crt
#輸出數據內容:
二進制數據
PEM編碼的證書簽名請求文件: -----BEGIN CERTIFICATE REQUEST-----
3、合成 .pfx
思路:使用crt + key 用來生成pfx證書文件。
openssl pkcs12 -export -out server.pfx -inkey pair.key -in crt.crt //unable to load certificates
or:
openssl pkcs12 -export -out server.pfx -inkey ***.key -in ***.cer
openssl pkcs12 -export -out server.pfx -inkey public.key -in crt.crt //unable to load private key
openssl pkcs12 -export -out server.pfx -inkey private.key -in crt.crt //unable to load certificates
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
openssl pkcs12 -export -out server.pfx -inkey pair.key -in encrypt_pri_key.pem //unable to load certificates
openssl pkcs12 -export -out server.pfx -inkey private.key -in encrypt_pri_key.pem //unable to load certificates
提示輸入 .key文件的密碼
提示輸入即將生成的 .pfx文件的密碼(需要輸入兩次)
若成功,會生成 server.pfx文件
4、另一種提取私鑰的方法,從公鑰對中提取:
從pfx證書中提取密鑰信息,並轉換為key格式(pfx使用pkcs12模式補足) 1、提取密鑰對(如果pfx證書已加密,會提示輸入密碼) openssl pkcs12 -in server.pfx -nocerts -nodes -out pair.key BEGIN PRIVATE KEY //1,和 4 相同,但比 4 多一些 Attributes 2、從密鑰對提取公鑰 openssl -in pair.key -pubout -out public.key BEGIN PUBLIC KEY //或者 //openssl rsa -in encrypt_pri_key.pem -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 --showcerts www.baidu.com:443
從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
openssl s_client -connect trade8.sctrade.com:10002
