SSL证书与私钥的编码格式和文件扩展名

证书格式(certificates)

X.509 使用一种称为抽象语法表示法 (ASN.1) 来表达证书的数据结构。

X.509 证书有不同的格式,例如 PEM、DER、PKCS#7 和 PKCS#12。 PEM 和 PKCS#7 格式使用 Base64 ASCII 编码,而 DER 和 PKCS#12 使用二进制编码。证书文件根据它们使用的格式和编码具有不同的扩展名。
不幸的是证书的扩展名并不能区分出证书使用的编码格式, 如以.cer为后缀的证书, 编码方式可能是Base64 ASCII 编码也可以是二进制编码。
PEM 格式:

大多数 CA(证书颁发机构)在 Base64 ASCII 编码文件中提供 PEM 格式的证书。证书文件类型可以是 .pem、.crt、.cer 或 .key。

  • .pem 文件可以在单个文件中包含服务器证书、中间证书和私钥。
  • .crt 或 .cer 文件可以用于服务器证书和中间证书。
  • .key 文件可用于私钥。

PEM 文件使用 ASCII 编码,因此您可以在任何文本编辑器(如记事本、MS word 等)中打开它们。

  • PEM 文件中的每个证书都包含在 —- BEGIN CERTIFICATE—- 和 —-END CERTIFICATE 之间—-报表。
  • 私钥 (PKCS#1 / PKCS#8)包含在 RSA —- BEGIN RSA PRIVATE KEY—– 和 —–END RSA PRIVATE KEY—– , —- BEGIN EC PRIVATE KEY—– 和 —–END EC PRIVATE KEY—– , —–BEGIN SM2 PRIVATE KEY—– 和 —–END SM2 PRIVATE KEY—–语句之间。
  • CSR (PKCS+10) 包含在 —–BEGIN CERTIFICATE REQUEST—– 和 —–END CERTIFICATE REQUEST—– 语句之间。

其中SM2的比较特殊:

openssl 3.0 版本

$ openssl ecparam -name SM2 -genkey -out sm2.key
$ openssl ec -in sm2.key -out sm2_1.key
read EC key
writing EC key
$ cat sm2.key
-----BEGIN SM2 PARAMETERS-----
BggqgRzPVQGCLQ==
-----END SM2 PARAMETERS-----
-----BEGIN PRIVATE KEY-----
MIGIAgEAMBQGCCqBHM9VAYItBggqgRzPVQGCLQRtMGsCAQEEIOwPify22mwkx8au
onuBd8lr8pZ1lu4VsBRQ1qKg3+ZSoUQDQgAEuSGYeABkTiBLw1OjvNRbbFJh03HL
bZvhhdiea4OOFm6FiDqx8u0ZeWmyEDSjfJRK04uJrArPMMEY8v5Dgs999Q==
-----END PRIVATE KEY-----
$ cat sm2_1.key
-----BEGIN SM2 PRIVATE KEY-----
MHcCAQEEIOwPify22mwkx8auonuBd8lr8pZ1lu4VsBRQ1qKg3+ZSoAoGCCqBHM9V
AYItoUQDQgAEuSGYeABkTiBLw1OjvNRbbFJh03HLbZvhhdiea4OOFm6FiDqx8u0Z
eWmyEDSjfJRK04uJrArPMMEY8v5Dgs999Q==
-----END SM2 PRIVATE KEY-----

openssl 1.1.1

生成的都为 EC

$ openssl ecparam -name SM2 -genkey  -out sm2.key
$ cat sm2.key
-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPtk3WLRBBQ9s29IOkZisJfZOkdtukSM8BcucGx5jpPMoAoGCCqBHM9V
AYItoUQDQgAEzAA69jGAaDZ2ZabQpGeSmtFsGoDf3rKJyE0oOfkjGoW8MWbXMEJi
YnDf8yEtHyvO3vAZEn4xKdl1dUKbWTeYFA==
-----END EC PRIVATE KEY-----
$ openssl ec -in sm2.key  -out sm2_1.key
read EC key
writing EC key
$ cat sm2_1.key
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPtk3WLRBBQ9s29IOkZisJfZOkdtukSM8BcucGx5jpPMoAoGCCqBHM9V
AYItoUQDQgAEzAA69jGAaDZ2ZabQpGeSmtFsGoDf3rKJyE0oOfkjGoW8MWbXMEJi
YnDf8yEtHyvO3vAZEn4xKdl1dUKbWTeYFA==
-----END EC PRIVATE KEY-----

这个问题目前还未解决

https://github.com/openssl/openssl/issues/20420

 

PKCS#7格式
PKCS#7 证书使用 Base64 ASCII 编码,文件扩展名为 .p7b 或 .p7c。
这种格式只能存储证书,不能存储私钥。
P7B 证书包含在“—–BEGIN PKCS7—–”和“—–END PKCS7—–”语句之间。

DER格式
证书或私钥采用二进制形式,包含在 .der 或 .cer 文件中。
这些证书主要用于基于 Java 的 Web 服务器。

PKCS#12格式
PKCS#12 证书采用二进制形式,包含在 .pfx 或 .p12 文件中。
PKCS#12 可以将服务器证书、中间证书和私钥存储在一个带有密码保护的.pfx 文件中。
这些证书主要用于 Windows 平台。

密钥格式(keys)

 

PKCS#1格式

定义 RSA 密钥的传统格式

-----BEGIN RSA PRIVATE KEY-----
RSAPrivateKey
-----END RSA PRIVATE KEY-----



-----BEGIN RSA PUBLIC KEY-----
RSAPublicKey
-----END RSA PUBLIC KEY-----
openssl genrsa -out private.pem 2048

如果是openssl3.0

openssl genrsa -traditional -out private.pem 2048

 

PKCS#8格式

PKCS#8支持多种加密算法, 还可以支持密码加密。

-----BEGIN PRIVATE KEY-----
PrivateKeyInfo ::= OneAsymmetricKey
-----END PRIVATE KEY-----


-----BEGIN ENCRYPTED PRIVATE KEY-----
EncryptedPrivateKeyInfo
-----END ENCRYPTED PRIVATE KEY-----

PKCS#8 与 PKCS#1转换

###Convert PKCS #1 -> PKCS #8

openssl pkcs8 -in private-pkcs1.pem -topk8 -out private-pkcs8.pem -nocrypt
openssl pkcs8 -in private-pkcs1.pem -topk8 -out private-pkcs8-enc.pem


###Convert PKCS #8 -> PKCS #1

openssl rsa -in private-pkcs8.pem -out private-pkcs1.pem

 

看下内部结构, 使用 openssl asn1parse

PKCS#1

$ openssl asn1parse -in private.pem
    0:d=0  hl=4 l=1187 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=4 l= 257 prim: INTEGER           :CEFF7BCD4F9D478B7DC5C07D0C752082D28598FF61F8FD49736E357630116BF0175B06E193B168C8BA3648D97BE584D959ED2685C8163341B0CD81AFB2CF26588A0090FB73C32865A0B0EE60126CC477D998CDDF4052B39CD76DA0A5EEF044054670E298DC7DE9BD30DDBC33D5F5FA70E631D9C1899577F3D6F1D0E4031E103FBC96AD660F19D24AE23F1136AF1FE615CC8D3093975BD68528BDD2C3AD5E91DF3D9C9C16B7D5195AC887F6CE84722A2ADD52A9520D699CEBBDDE19E9EB9317707EED80346F47A2705BA372BAFC4A3C925E49E662EA8F25ABE50B840C75F07ADDC25AD23D051A81930F8CE4581CDE6D984E668DB12B37DB1663DBE5A86C6F836F
  268:d=1  hl=2 l=   3 prim: INTEGER           :010001
  273:d=1  hl=4 l= 256 prim: INTEGER           :46B521A283C00B68DC391923FE05E2699DA4F21AC66A2987160D7EE894C9D6AF8822D96A63AB75CA1F459CC3E19D08B0C0159093A141E81757E0131D23BCBBF2018DE8F863D635ADE5629AC2A9788AF20F9BB13342031E0484D81748A7225E71D8DA85A4C6A8A217B4A201804965813B607E85CE2503B01A54817CA3EE66AE10A23FB763A161B49DDE51511618EAB4C3A8008305D3930692B363F1DD8698E6F4B6A31068E8AEC9FAB70843AE75218738014E47F2F1FCA3DD639D52F971029F2FB85FFEC7B1E4F1E824C5B08EBD0F2BC6833E65943CC83729B6A37E561898528CD585F214AA9E2ED7C68AF020E5C7F3130A3BBBEFE24D0DB776F11CB83AE16A3D
  533:d=1  hl=3 l= 129 prim: INTEGER           :E98BE0C1D95856C0CDF5A94E019D183D7A0B3A5E7D41449D93FEFB01749073FBD222EC9B6AA5A27B4A637A770A59BBBCAF12A46A4462918FCBE0B4DC8C2F185767B8824F68FDD801881A6EE283CB5459A59082FF5B37F529E6AB1F054D9CF48FE0847CB7615FC6B04267646ACF2EB63526D450F4DA38CE0210B535FF46DC69BD
  665:d=1  hl=3 l= 129 prim: INTEGER           :E2E62FEA19B652533AD3EE33C640FABF78512D82DCAC9672974851286BCA7DB8D0E1C0DD25E29AD08BE4D6D56DE4DA7A5D681A6F90A1EF07080ECDE0CAA9063F3A2B207D8DF3861DCF49F1D5E6EF4BF71DB924F7866493484C5D316841BF8C4E59A62C243AE2954384A1BB8DA885206A9CD9A7CDF3EF69B362736D7F37AE569B
  797:d=1  hl=3 l= 129 prim: INTEGER           :8A07369DBAE3BFDA119FC8212748FE438F36C59784B5A764EE4BFB735FBDE41E8792467E902836806175ABB26136A98319818E14943821497838650C17F9D98C06EC007008604662995AEE0007DE8B0AB4945527B074C0FBB3AD9D16D849142D588754E258B56F4B4AE3AA7089E454A1D342165AB0027496B9E32F77A11CB18D
  929:d=1  hl=3 l= 128 prim: INTEGER           :603697AEBF046ED85823B1E846731B60C1963AA4390AFE28CD399F2072C4C496F00C2A8A1C1C80E559CCC9C46AFB1621B92601BFB926D182BBC9FB470CE8AB7B7820FD80000779A17E5AAEAFB36359650A378E135FEB9A00985114384F58F817E92FEB9BD9546752E014ECC0DEEAC49A30B4A2D15454FB0F53F9FA3E6DD0016D
 1060:d=1  hl=3 l= 128 prim: INTEGER           :7603381CFB4845A7CD70C96AA0595AABC06C8FA25D2F0D808E27FA7A4C695891CF24EAB0A8BCF92E3B9DA109CBE9F2FB9766E357D277972B217BC6129BC3CAF0E317F6C7106DAFD30AE3C4E58C6E1B734C4F7E6D6E36E498BE4BDFAD7C5A2B61D8E48CC267C65D0F13792138EE144CA73CD936F0BDDE7CC5BFC43BAE57A7BA41

PKCS#8

$ openssl asn1parse -in private-pkcs8.pem
    0:d=0  hl=4 l=1213 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=2 l=  13 cons: SEQUENCE
    9:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   20:d=2  hl=2 l=   0 prim: NULL
   22:d=1  hl=4 l=1191 prim: OCTET STRING      [HEX DUMP]:308204A30201000282010100CEFF7BCD4F9D478B7DC5C07D0C752082D28598FF61F8FD49736E357630116BF0175B06E193B168C8BA3648D97BE584D959ED2685C8163341B0CD81AFB2CF26588A0090FB73C32865A0B0EE60126CC477D998CDDF4052B39CD76DA0A5EEF044054670E298DC7DE9BD30DDBC33D5F5FA70E631D9C1899577F3D6F1D0E4031E103FBC96AD660F19D24AE23F1136AF1FE615CC8D3093975BD68528BDD2C3AD5E91DF3D9C9C16B7D5195AC887F6CE84722A2ADD52A9520D699CEBBDDE19E9EB9317707EED80346F47A2705BA372BAFC4A3C925E49E662EA8F25ABE50B840C75F07ADDC25AD23D051A81930F8CE4581CDE6D984E668DB12B37DB1663DBE5A86C6F836F02030100010282010046B521A283C00B68DC391923FE05E2699DA4F21AC66A2987160D7EE894C9D6AF8822D96A63AB75CA1F459CC3E19D08B0C0159093A141E81757E0131D23BCBBF2018DE8F863D635ADE5629AC2A9788AF20F9BB13342031E0484D81748A7225E71D8DA85A4C6A8A217B4A201804965813B607E85CE2503B01A54817CA3EE66AE10A23FB763A161B49DDE51511618EAB4C3A8008305D3930692B363F1DD8698E6F4B6A31068E8AEC9FAB70843AE75218738014E47F2F1FCA3DD639D52F971029F2FB85FFEC7B1E4F1E824C5B08EBD0F2BC6833E65943CC83729B6A37E561898528CD585F214AA9E2ED7C68AF020E5C7F3130A3BBBEFE24D0DB776F11CB83AE16A3D02818100E98BE0C1D95856C0CDF5A94E019D183D7A0B3A5E7D41449D93FEFB01749073FBD222EC9B6AA5A27B4A637A770A59BBBCAF12A46A4462918FCBE0B4DC8C2F185767B8824F68FDD801881A6EE283CB5459A59082FF5B37F529E6AB1F054D9CF48FE0847CB7615FC6B04267646ACF2EB63526D450F4DA38CE0210B535FF46DC69BD02818100E2E62FEA19B652533AD3EE33C640FABF78512D82DCAC9672974851286BCA7DB8D0E1C0DD25E29AD08BE4D6D56DE4DA7A5D681A6F90A1EF07080ECDE0CAA9063F3A2B207D8DF3861DCF49F1D5E6EF4BF71DB924F7866493484C5D316841BF8C4E59A62C243AE2954384A1BB8DA885206A9CD9A7CDF3EF69B362736D7F37AE569B028181008A07369DBAE3BFDA119FC8212748FE438F36C59784B5A764EE4BFB735FBDE41E8792467E902836806175ABB26136A98319818E14943821497838650C17F9D98C06EC007008604662995AEE0007DE8B0AB4945527B074C0FBB3AD9D16D849142D588754E258B56F4B4AE3AA7089E454A1D342165AB0027496B9E32F77A11CB18D028180603697AEBF046ED85823B1E846731B60C1963AA4390AFE28CD399F2072C4C496F00C2A8A1C1C80E559CCC9C46AFB1621B92601BFB926D182BBC9FB470CE8AB7B7820FD80000779A17E5AAEAFB36359650A378E135FEB9A00985114384F58F817E92FEB9BD9546752E014ECC0DEEAC49A30B4A2D15454FB0F53F9FA3E6DD0016D0281807603381CFB4845A7CD70C96AA0595AABC06C8FA25D2F0D808E27FA7A4C695891CF24EAB0A8BCF92E3B9DA109CBE9F2FB9766E357D277972B217BC6129BC3CAF0E317F6C7106DAFD30AE3C4E58C6E1B734C4F7E6D6E36E498BE4BDFAD7C5A2B61D8E48CC267C65D0F13792138EE144CA73CD936F0BDDE7CC5BFC43BAE57A7BA41

可以看到PKCS#8 在 22 字节偏移位置就是PKCS#1的内容

$ openssl asn1parse -in private-pkcs8.pem -strparse 22
    0:d=0  hl=4 l=1187 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=4 l= 257 prim: INTEGER           :CEFF7BCD4F9D478B7DC5C07D0C752082D28598FF61F8FD49736E357630116BF0175B06E193B168C8BA3648D97BE584D959ED2685C8163341B0CD81AFB2CF26588A0090FB73C32865A0B0EE60126CC477D998CDDF4052B39CD76DA0A5EEF044054670E298DC7DE9BD30DDBC33D5F5FA70E631D9C1899577F3D6F1D0E4031E103FBC96AD660F19D24AE23F1136AF1FE615CC8D3093975BD68528BDD2C3AD5E91DF3D9C9C16B7D5195AC887F6CE84722A2ADD52A9520D699CEBBDDE19E9EB9317707EED80346F47A2705BA372BAFC4A3C925E49E662EA8F25ABE50B840C75F07ADDC25AD23D051A81930F8CE4581CDE6D984E668DB12B37DB1663DBE5A86C6F836F
  268:d=1  hl=2 l=   3 prim: INTEGER           :010001
  273:d=1  hl=4 l= 256 prim: INTEGER           :46B521A283C00B68DC391923FE05E2699DA4F21AC66A2987160D7EE894C9D6AF8822D96A63AB75CA1F459CC3E19D08B0C0159093A141E81757E0131D23BCBBF2018DE8F863D635ADE5629AC2A9788AF20F9BB13342031E0484D81748A7225E71D8DA85A4C6A8A217B4A201804965813B607E85CE2503B01A54817CA3EE66AE10A23FB763A161B49DDE51511618EAB4C3A8008305D3930692B363F1DD8698E6F4B6A31068E8AEC9FAB70843AE75218738014E47F2F1FCA3DD639D52F971029F2FB85FFEC7B1E4F1E824C5B08EBD0F2BC6833E65943CC83729B6A37E561898528CD585F214AA9E2ED7C68AF020E5C7F3130A3BBBEFE24D0DB776F11CB83AE16A3D
  533:d=1  hl=3 l= 129 prim: INTEGER           :E98BE0C1D95856C0CDF5A94E019D183D7A0B3A5E7D41449D93FEFB01749073FBD222EC9B6AA5A27B4A637A770A59BBBCAF12A46A4462918FCBE0B4DC8C2F185767B8824F68FDD801881A6EE283CB5459A59082FF5B37F529E6AB1F054D9CF48FE0847CB7615FC6B04267646ACF2EB63526D450F4DA38CE0210B535FF46DC69BD
  665:d=1  hl=3 l= 129 prim: INTEGER           :E2E62FEA19B652533AD3EE33C640FABF78512D82DCAC9672974851286BCA7DB8D0E1C0DD25E29AD08BE4D6D56DE4DA7A5D681A6F90A1EF07080ECDE0CAA9063F3A2B207D8DF3861DCF49F1D5E6EF4BF71DB924F7866493484C5D316841BF8C4E59A62C243AE2954384A1BB8DA885206A9CD9A7CDF3EF69B362736D7F37AE569B
  797:d=1  hl=3 l= 129 prim: INTEGER           :8A07369DBAE3BFDA119FC8212748FE438F36C59784B5A764EE4BFB735FBDE41E8792467E902836806175ABB26136A98319818E14943821497838650C17F9D98C06EC007008604662995AEE0007DE8B0AB4945527B074C0FBB3AD9D16D849142D588754E258B56F4B4AE3AA7089E454A1D342165AB0027496B9E32F77A11CB18D
  929:d=1  hl=3 l= 128 prim: INTEGER           :603697AEBF046ED85823B1E846731B60C1963AA4390AFE28CD399F2072C4C496F00C2A8A1C1C80E559CCC9C46AFB1621B92601BFB926D182BBC9FB470CE8AB7B7820FD80000779A17E5AAEAFB36359650A378E135FEB9A00985114384F58F817E92FEB9BD9546752E014ECC0DEEAC49A30B4A2D15454FB0F53F9FA3E6DD0016D
 1060:d=1  hl=3 l= 128 prim: INTEGER           :7603381CFB4845A7CD70C96AA0595AABC06C8FA25D2F0D808E27FA7A4C695891CF24EAB0A8BCF92E3B9DA109CBE9F2FB9766E357D277972B217BC6129BC3CAF0E317F6C7106DAFD30AE3C4E58C6E1B734C4F7E6D6E36E498BE4BDFAD7C5A2B61D8E48CC267C65D0F13792138EE144CA73CD936F0BDDE7CC5BFC43BAE57A7BA41

 

ECC 相关操作  https://www.scottbrady91.com/openssl/creating-elliptical-curve-keys-using-openssl

PKCS标准:https://en.wikipedia.org/wiki/PKCS

How to generate x509v3 Extensions in the End user certificate:

https://access.redhat.com/solutions/28965

x509v3_config:

https://www.openssl.org/docs/manmaster/man5/x509v3_config.html

How to add X.509 extensions to certificate OpenSSL

https://www.golinuxcloud.com/add-x509-extensions-to-certificate-openssl/

Adding AuthorityKeyIdentifier to a CertRequest

https://stackoverflow.com/questions/19163484/adding-authoritykeyidentifier-to-a-certrequest

Confusion over PKCS#1 and “traditional” options with OpenSSL

https://crypto.stackexchange.com/questions/103582/confusion-over-pkcs1-and-traditional-options-with-openssl

OpenSSL encrypt DER format private key

https://security.stackexchange.com/questions/244668/openssl-encrypt-der-format-private-key

Openssl ECDSA : private key passphrase

https://stackoverflow.com/questions/36968896/openssl-ecdsa-private-key-passphrase

参考及引用

https://www.tutorialsteacher.com/https/ssl-certificate-format
https://blog.ndpar.com/2017/04/17/p1-p8/
图片 from 江金倫

 

Comments are closed.