美文网首页
浅谈HTTPS证书文件格式

浅谈HTTPS证书文件格式

作者: 若兮相言 | 来源:发表于2023-06-06 16:02 被阅读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操作

    • 生成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 (命令报错,不可执行)
    
    输出到文件
    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
    

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

    相关文章

      网友评论

          本文标题:浅谈HTTPS证书文件格式

          本文链接:https://www.haomeiwen.com/subject/latoldtx.html