浅谈HTTPS证书文件格式

2023-06-06  本文已影响0人  若兮相言

我们在使用HTTPS加密时,通常需要申请2个文件,一个是证书,一个是私钥,其中证书文件常见的后缀有pem,crt,cer等,那这些格式都有什么区别,里面的存储格式是怎样的?存储了什么内容?今天来研究一下。

证书类型

常用的证书类型有:X.509证书、PKCS#7证书、PKCS#12证书

从使用场景的角度来对比 X.509、PKCS#7 和 PKCS#12,可以简要总结如下:

  1. X.509:

    • 使用场景:X.509 数字证书主要用于建立和验证安全通信,例如在 SSL/TLS 加密通信中进行客户端和服务器的身份认证。
    • 典型应用:SSL/TLS、VPN、S/MIME(安全的电子邮件)等。
  2. PKCS#7:

    • 使用场景:PKCS#7 主要用于封装和传输加密数据、数字签名和证书等信息,提供了一种通用的数据结构和容器格式。
    • 典型应用:数字签名、加密数据传输、数字证书交换、证书吊销列表(CRL)等。
  3. PKCS#12:

    • 使用场景:PKCS#12 主要用于存储和传输个人身份证书、私钥和相关信息,方便在不同设备或应用程序之间共享和导入。
    • 典型应用:个人身份证书的导出和导入、客户端证书存储、身份验证、加密私钥的保护等。

需要注意的是,这些使用场景并不是绝对的,有一些重叠和交叉的情况。例如,PKCS#12 文件可以包含 X.509 数字证书和相关的私钥,并且在一些情况下,PKCS#7 可能会用于封装和传输 X.509 数字证书和 CRL。

总结:X.509只包含公钥,没有私钥,可用于放在客户端使用,用于加密、验签,PKCS#12同时包含了公钥和私钥,一般放在服务端使用,用于解密、签名(记得做微信支付时,有些双向加密的场景就要使用到p12证书,因为要有私钥才可以双向加密)

文件存储格式

这里是常见证书文件后缀名的一些区别说明:

  1. .pem:

    • PEM(Privacy-Enhanced Mail)格式是一种基于ASCII编码的文件格式,通常用于存储X.509证书、私钥和其他相关数据。
    • PEM格式的证书文件可以包含BEGIN和END标记,以及Base64编码的证书数据。
    • .pem后缀通常用于表示包含单个PEM格式证书的文件。
  2. .crt:

    • .crt后缀通常用于表示X.509证书文件。
    • .crt文件可以使用不同的编码格式,包括DER编码或PEM编码。具体取决于文件的内容。
  3. .cer:

    • .cer后缀也通常用于表示X.509证书文件。
    • 与.crt文件类似,.cer文件可以使用不同的编码格式,包括DER编码或PEM编码。
  4. .der:

    • .der后缀表示DER(Distinguished Encoding Rules)编码的二进制格式证书文件。
    • DER格式是一种二进制格式,不像PEM格式那样使用Base64编码的ASCII文本。
  5. .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-----

这是我解析自签发的一张证书(省略部分私密信息用...代替),可以看到,里面存有公钥、X509协议的版本,序列号,约定的签名算法(RSA只是非对称加密的一种,还有ECC等),签发者,有效期,签发目标,签发目标的公钥,而签发的DNS信息作为一个扩展信息被标注出来。

证书的二进制格式不是HTTP证书专有的,而是遵循了一个叫ASN.1的协议,我们同样可以使用openssl解析符合ASN.1格式的数据

[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操作

openssl genrsa -out private_pkcs1.pem 2048
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
openssl rsa -in private_pkcs1.pem -out public_pkcs1.der -pubout -RSAPublicKey_out -outform DER
openssl rsa -in private_pkcs1.pem -text -noout
openssl rsa -in public_pkcs8.pem -out public_pkcs1.pem -pubin -RSAPublicKey_out
openssl pkcs8 -in private_pkcs1.pem -out private_pkcs8.pem -topk8 -nocrypt
openssl rsa -in private_pkcs8.pem -out private_pkcs1.pem
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
输出到命令行窗口
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 (命令报错,不可执行)

输出到文件
openssl rsa -in private_pkcs8.pem -text -out out.txt
openssl pkcs12 -in demo_749054.pfx -nocerts -nodes -out private_pkcs8.pem

参考
RSA密钥格式解析
RFC 8017
RFC 2347
RSA算法原理(阮一峰)

上一篇下一篇

猜你喜欢

热点阅读