介绍

每个人都喜欢PEM和用于以便携式格式保存加密密钥和证书的ASN.1结构。好吧..如果他们真的被记录下来,每个人都会这样做。但是,找到每个DER或PEM格式文件中的结构是一个很大的壮举。

由于我们需要这些信息,我们也会在这里分享,以帮助他人寻求知识和理解;)

ASN.1和DER编码

在RSA,PKCS#1和SSL / TLS社区内ASN.1的分辨编码规则(DER)编码用于以便携式格式表示密钥,证书等。尽管ASN.1不是最容易理解的表示格式并且带来了很多复杂性,但它确实有其优点。证书或密钥信息存储在ASN.1的二进制DER中,提供RSA,SSL和TLS的应用程序应处理DER编码以读取信息。

PEM文件

由于DER编码导致编码数据的真正二进制表示,因此设计了一种格式,以便能够以可打印字符的编码方式发送这些格式,以便您可以实际邮寄这些内容。我现在关注的格式是PEM格式。

我们将看到的大多数PEM格式的文​​件是由OpenSSL在生成或导出RSA私钥或公钥和X509证书时生成的。

本质上,PEM文件只是DER编码数据的base64编码版本。为了区分外部DER编码字符串中的数据类型,数据周围存在页眉和页脚。PEM编码文件的示例是:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYfnvWtC8Id5bPKae5yXSxQTt
+Zpul6AnnZWfI2TtIarvjHBFUtXRo96y7hoL4VWOPKGCsRqMFDkrbeUjRrx8iL91
4/srnyf6sh9c8Zk04xEOpK1ypvBz+Ks4uZObtjnnitf0NBGdjMKxveTq+VE7BWUI
yQjtQ8mbDOsiLLvh7wIDAQAB
-----END PUBLIC KEY-----

第一行和最后一行表示内部应该预期的DER格式。里面的数据是DER编码信息的base64编码版本。

格式

所以这一切都很好。但是在每个不同的文件中你应该期待什么结构?请看下面的不同格式的解释。

RSA公钥文件(PKCS#1)

RSA公钥PEM文件特定于RSA密钥。

它以标签开头和结尾:

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

在base64编码数据中,存在以下DER结构:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

公钥文件(PKCS#8)

由于RSA不是专门用于X509和SSL / TLS,因此PKCS#8形式提供了更通用的密钥格式,它标识了公钥的类型并包含相关数据。

它以标签开头和结尾:

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

在base64编码数据中,存在以下DER结构:

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

因此,对于RSA公钥,OID是1.2.840.113549.1.1.1,并且有一个RSAPublicKey作为PublicKey密钥数据bitstring。

RSA私钥文件(PKCS#1)

RSA私钥PEM文件特定于RSA密钥。

它以标签开头和结尾:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

在base64编码数据中,存在以下DER结构:

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
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

私钥文件(PKCS#8)

由于RSA不是专门用于X509和SSL / TLS,因此PKCS#8形式的更通用密钥格式可用于标识私钥的类型并包含相关数据。

未加密的PKCS#8编码数据以标签开头和结尾:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

在base64编码数据中,存在以下DER结构:

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      OCTET STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

因此对于RSA私钥,OID是1.2.840.113549.1.1.1并且存在RSAPrivateKey作为PrivateKey密钥数据八位字节串。

加密的PKCS#8编码数据以标签开头和结尾:

-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64 ENCODED DATA
-----END ENCRYPTED PRIVATE KEY-----

在base64编码数据中,存在以下DER结构:

EncryptedPrivateKeyInfo ::= SEQUENCE {
  encryptionAlgorithm  EncryptionAlgorithmIdentifier,
  encryptedData        EncryptedData
}

EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier

EncryptedData ::= OCTET STRING

EncryptedData OCTET STRING是PKCS#8 PrivateKeyInfo(见上文)。

这有帮助吗?