DER 和 PEM 中的 ASN.1 关键结构

https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem

介绍

每个人都喜欢 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 密钥数据位串。

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(见上文)。

这有帮助吗?

你可能感兴趣的:(DER 和 PEM 中的 ASN.1 关键结构)