介绍#

每个人都喜欢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(见上文)。

这有帮助吗?#