我們在使用HTTPS加密時众羡,通常需要申請2個文件勋颖,一個是證書嗦嗡,一個是私鑰,其中證書文件常見的后綴有pem,crt,cer等饭玲,那這些格式都有什么區(qū)別侥祭,里面的存儲格式是怎樣的?存儲了什么內容?今天來研究一下。
證書類型
常用的證書類型有:X.509證書矮冬、PKCS#7證書谈宛、PKCS#12證書
從使用場景的角度來對比 X.509、PKCS#7 和 PKCS#12胎署,可以簡要總結如下:
-
X.509:
- 使用場景:X.509 數(shù)字證書主要用于建立和驗證安全通信入挣,例如在 SSL/TLS 加密通信中進行客戶端和服務器的身份認證。
- 典型應用:SSL/TLS硝拧、VPN径筏、S/MIME(安全的電子郵件)等。
-
PKCS#7:
- 使用場景:PKCS#7 主要用于封裝和傳輸加密數(shù)據(jù)障陶、數(shù)字簽名和證書等信息滋恬,提供了一種通用的數(shù)據(jù)結構和容器格式。
- 典型應用:數(shù)字簽名抱究、加密數(shù)據(jù)傳輸恢氯、數(shù)字證書交換、證書吊銷列表(CRL)等鼓寺。
-
PKCS#12:
- 使用場景:PKCS#12 主要用于存儲和傳輸個人身份證書勋拟、私鑰和相關信息,方便在不同設備或應用程序之間共享和導入妈候。
- 典型應用:個人身份證書的導出和導入敢靡、客戶端證書存儲、身份驗證苦银、加密私鑰的保護等啸胧。
需要注意的是,這些使用場景并不是絕對的幔虏,有一些重疊和交叉的情況纺念。例如,PKCS#12 文件可以包含 X.509 數(shù)字證書和相關的私鑰想括,并且在一些情況下陷谱,PKCS#7 可能會用于封裝和傳輸 X.509 數(shù)字證書和 CRL。
總結:X.509只包含公鑰瑟蜈,沒有私鑰烟逊,可用于放在客戶端使用,用于加密踪栋、驗簽焙格,PKCS#12同時包含了公鑰和私鑰图毕,一般放在服務端使用夷都,用于解密、簽名(記得做微信支付時,有些雙向加密的場景就要使用到p12證書囤官,因為要有私鑰才可以雙向加密)
文件存儲格式
這里是常見證書文件后綴名的一些區(qū)別說明:
-
.pem:
- PEM(Privacy-Enhanced Mail)格式是一種基于ASCII編碼的文件格式冬阳,通常用于存儲X.509證書、私鑰和其他相關數(shù)據(jù)党饮。
- PEM格式的證書文件可以包含BEGIN和END標記肝陪,以及Base64編碼的證書數(shù)據(jù)。
- .pem后綴通常用于表示包含單個PEM格式證書的文件刑顺。
-
.crt:
- .crt后綴通常用于表示X.509證書文件氯窍。
- .crt文件可以使用不同的編碼格式,包括DER編碼或PEM編碼蹲堂。具體取決于文件的內容狼讨。
-
.cer:
- .cer后綴也通常用于表示X.509證書文件。
- 與.crt文件類似柒竞,.cer文件可以使用不同的編碼格式政供,包括DER編碼或PEM編碼。
-
.der:
- .der后綴表示DER(Distinguished Encoding Rules)編碼的二進制格式證書文件朽基。
- DER格式是一種二進制格式布隔,不像PEM格式那樣使用Base64編碼的ASCII文本。
-
.pfx / .p12:
- .pfx或.p12后綴表示PKCS#12格式的證書文件稼虎。
- PKCS#12格式是一種二進制格式衅檀,可以包含證書、私鑰和中間證書等霎俩。
- .pfx或.p12文件通常使用密碼進行加密术吝。
總結:der是證書原本的二進制格式,pem是der進行base64編碼后的結果茸苇,crt和cer則只是另外一種文件后綴名排苍,里面的內容可以是二進制也可以是base64格式。
明白了證書文件的格式学密,那證書里都存了些什么呢?由于證書格式最終都是二進制存儲的淘衙,我們使用openssl來解析看看
[ych@centos internal.rxxy.icu]$ openssl x509 -in internal.rxxy.icu.crt -pubkey --text
-----BEGIN PUBLIC KEY-----
MIIBIjAN...
-----END PUBLIC KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
5e:9e:bf:e2:4e:c3:1d:e4:36:c0:01:c0:83:43:d4:86:4a:6b:02:9f
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = Beijing, L = HaiDian, O = xxx, CN = xxx.cn
Validity
Not Before: May 31 09:13:28 2023 GMT
Not After : May 28 09:13:28 2033 GMT
Subject: C = CN, ST = BeiJing, L = HaiDian, O = xxx, CN = xxx
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c2:6d:1e:97...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:*.internal.rxxy.icu
Signature Algorithm: sha256WithRSAEncryption
84:a1:c3:1f:63:42...
-----BEGIN CERTIFICATE-----
MIIEczCCAlugAwIBAgIUXp6/4k7DHeQ2...
-----END CERTIFICATE-----
這是我解析自簽發(fā)的一張證書(省略部分私密信息用...代替),可以看到腻暮,里面存有公鑰彤守、X509協(xié)議的版本,序列號哭靖,約定的簽名算法(RSA只是非對稱加密的一種具垫,還有ECC等),簽發(fā)者试幽,有效期筝蚕,簽發(fā)目標,簽發(fā)目標的公鑰,而簽發(fā)的DNS信息作為一個擴展信息被標注出來起宽。
證書的二進制格式不是HTTP證書專有的洲胖,而是遵循了一個叫ASN.1的協(xié)議,我們同樣可以使用openssl解析符合ASN.1格式的數(shù)據(jù)
[ych@centos-oracle internal.rxxy.icu]$ openssl asn1parse -in internal.rxxy.icu.crt
0:d=0 hl=4 l=1139 cons: SEQUENCE
4:d=1 hl=4 l= 603 cons: SEQUENCE
8:d=2 hl=2 l= 3 cons: cont [ 0 ]
10:d=3 hl=2 l= 1 prim: INTEGER :02
13:d=2 hl=2 l= 20 prim: INTEGER :5E9EBFE...
35:d=2 hl=2 l= 13 cons: SEQUENCE
37:d=3 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
48:d=3 hl=2 l= 0 prim: NULL
50:d=2 hl=2 l= 97 cons: SEQUENCE
52:d=3 hl=2 l= 11 cons: SET
54:d=4 hl=2 l= 9 cons: SEQUENCE
56:d=5 hl=2 l= 3 prim: OBJECT :countryName
61:d=5 hl=2 l= 2 prim: PRINTABLESTRING :CN
65:d=3 hl=2 l= 16 cons: SET
67:d=4 hl=2 l= 14 cons: SEQUENCE
69:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
74:d=5 hl=2 l= 7 prim: UTF8STRING :Beijing
83:d=3 hl=2 l= 16 cons: SET
85:d=4 hl=2 l= 14 cons: SEQUENCE
87:d=5 hl=2 l= 3 prim: OBJECT :localityName
92:d=5 hl=2 l= 7 prim: UTF8STRING :HaiDian
101:d=3 hl=2 l= 19 cons: SET
103:d=4 hl=2 l= 17 cons: SEQUENCE
105:d=5 hl=2 l= 3 prim: OBJECT :organizationName
110:d=5 hl=2 l= 10 prim: UTF8STRING :xxx
122:d=3 hl=2 l= 25 cons: SET
124:d=4 hl=2 l= 23 cons: SEQUENCE
126:d=5 hl=2 l= 3 prim: OBJECT :commonName
131:d=5 hl=2 l= 16 prim: UTF8STRING :xxx.cn
149:d=2 hl=2 l= 30 cons: SEQUENCE
151:d=3 hl=2 l= 13 prim: UTCTIME :230531091328Z
166:d=3 hl=2 l= 13 prim: UTCTIME :330528091328Z
181:d=2 hl=2 l= 98 cons: SEQUENCE
183:d=3 hl=2 l= 11 cons: SET
185:d=4 hl=2 l= 9 cons: SEQUENCE
187:d=5 hl=2 l= 3 prim: OBJECT :countryName
192:d=5 hl=2 l= 2 prim: PRINTABLESTRING :CN
196:d=3 hl=2 l= 16 cons: SET
198:d=4 hl=2 l= 14 cons: SEQUENCE
200:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
205:d=5 hl=2 l= 7 prim: UTF8STRING :BeiJing
214:d=3 hl=2 l= 16 cons: SET
216:d=4 hl=2 l= 14 cons: SEQUENCE
218:d=5 hl=2 l= 3 prim: OBJECT :localityName
223:d=5 hl=2 l= 7 prim: UTF8STRING :HaiDian
232:d=3 hl=2 l= 19 cons: SET
234:d=4 hl=2 l= 17 cons: SEQUENCE
236:d=5 hl=2 l= 3 prim: OBJECT :organizationName
241:d=5 hl=2 l= 10 prim: UTF8STRING :xxx
253:d=3 hl=2 l= 26 cons: SET
255:d=4 hl=2 l= 24 cons: SEQUENCE
257:d=5 hl=2 l= 3 prim: OBJECT :commonName
262:d=5 hl=2 l= 17 prim: UTF8STRING :xxx
281:d=2 hl=4 l= 290 cons: SEQUENCE
285:d=3 hl=2 l= 13 cons: SEQUENCE
287:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
298:d=4 hl=2 l= 0 prim: NULL
300:d=3 hl=4 l= 271 prim: BIT STRING
575:d=2 hl=2 l= 34 cons: cont [ 3 ]
577:d=3 hl=2 l= 32 cons: SEQUENCE
579:d=4 hl=2 l= 30 cons: SEQUENCE
581:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Alternative Name
586:d=5 hl=2 l= 23 prim: OCTET STRING [HEX DUMP]:301582132A2E696...
611:d=1 hl=2 l= 13 cons: SEQUENCE
613:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
624:d=2 hl=2 l= 0 prim: NULL
626:d=1 hl=4 l= 513 prim: BIT STRING
可以看到坯沪,
下面來深入了解下證書的結構PKCS#1&PKCS#8
PKCS#1
PKCS#1形式的密鑰專指RSA的密鑰绿映,如果一個ECC的密鑰就無法用PKCS#1形式來表達
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER -- (inverse of q) mod p
}
PKCS#8
既可以表示RSA密鑰,又可以表示ECC的密鑰
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
privateKey PrivateKey,
attributes [0] Attributes OPTIONAL
}
下面是一些使用openssl查看和操作解析證書的命令腐晾,再深入就要解析證書里的公鑰和私鑰啦叉弦,推薦看完阮一峰的RSA算法原理后再來研究,我就暫時止步于此了哈哈-_-||(其實是被勸退)
OPENSSL操作
- 生成RSA密鑰PKCS#1
openssl genrsa -out private_pkcs1.pem 2048
- 從生成的RSA密鑰中提取RSA公鑰
openssl rsa -in private_pkcs1.pem -out public_pkcs8.pem -pubout
openssl rsa -in private_pkcs1.pem -out public_pkcs1.pem -pubout -RSAPublicKey_out
openssl rsa -in private_pkcs8.pem -out public_pkcs8.pem -pubout
openssl rsa -in private_pkcs8.pem -out public_pkcs1.pem -pubout -RSAPublicKey_out
- 導出DER格式的公鑰
openssl rsa -in private_pkcs1.pem -out public_pkcs1.der -pubout -RSAPublicKey_out -outform DER
- 查看我們密鑰的n藻糖、e卸奉、d值
openssl rsa -in private_pkcs1.pem -text -noout
- RSA公鑰格式轉換(PKCS#8 ==> PKCS#1)
openssl rsa -in public_pkcs8.pem -out public_pkcs1.pem -pubin -RSAPublicKey_out
- RSA私鑰格式轉換(PKCS#1 ==> PKCS#8)
openssl pkcs8 -in private_pkcs1.pem -out private_pkcs8.pem -topk8 -nocrypt
- RSA私鑰格式轉換(PKCS#8 ==> PKCS#1)
openssl rsa -in private_pkcs8.pem -out private_pkcs1.pem
- RSA公鑰編碼格式轉換(PKCS#8:PEM ==> DER)
openssl rsa -pubin -in public_pkcs8.pem -out public_pkcs8.der -outform DER
openssl rsa -in private_pkcs8.pem -out private_pkcs1.der -outform DER
- 查看私鑰及公鑰n、e颖御、d
輸出到命令行窗口
openssl rsa -in private_pkcs8.pem -text
openssl rsa -in private_pkcs1.pem -text
openssl rsa -in public_pkcs8.pem -text -pubin
openssl rsa -in public_pkcs1.pem -text -pubin (命令報錯榄棵,不可執(zhí)行)
輸出到文件
openssl rsa -in private_pkcs8.pem -text -out out.txt
- 從pfx文件中提取私鑰(==> PKCS#8)
openssl pkcs12 -in demo_749054.pfx -nocerts -nodes -out private_pkcs8.pem