PEM 文件格式在哪里指定?

发布于 2024-10-23 01:15:47 字数 139 浏览 3 评论 0原文

我需要解析 .PEM 文件。
我知道 RFC 1421-24 中定义了“增强隐私的电子邮件”标准。但他们似乎没有提到我在 OpenSSL .pem 文件中找到的一些文本(例如“关键属性”、“开始证书”等......) 这是 OpenSSL 特定的格式吗?

I need to parse .PEM files.
I know that the standard for "Privacy-enhanced Electronic Mail" is defined in RFCs 1421-24. But they don't seem to mention some text I find inside OpenSSL .pem files (eg. "Key Attributes", "BEGIN CERTIFICATE", etc...)
Is this an OpenSSL-specific format?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

友欢 2024-10-30 01:15:47

很长一段时间以来,关于信息加密交换的 PEM 格式都没有正式规范。 PEM 是文本编码,但实际编码的内容取决于上下文。 2015 年 4 月,IETF 批准了 RFC 7468,最终记录各种实现如何使用 PEM 文本编码交换数据。以下列表直接取自 RFC,描述了用于以下场景的 PEM 格式:

  1. 证书、证书吊销列表 (CRL) 和主题
    互联网中的公钥信息结构 X.509 公钥
    基础设施证书和证书吊销列表 (CRL)
    简介[RFC5280]
  2. PKCS #10:认证请求语法[RFC2986]
  3. PKCS #7:加密消息语法[RFC2315]
  4. 加密消息语法[RFC5652]
  5. PKCS #8:私钥信息语法 [RFC5208],重命名为 One
    非对称密钥包 [RFC5958]中的非对称密钥,并加密
    同一文档中的私钥信息语法。
  6. 互联网属性证书中的属性证书
    授权配置文件[RFC5755]

根据此 RFC,对于上述场景,您可以预期以下标签位于 BEGIN 页眉和 END 页脚内。 RFC 的图 4 有更多详细信息,包括相应的 ASN.1 类型。

但这并不是故事的全部。 RFC 是通过查看现有实现并记录它们所做的事情来编写的。 RFC并不是首先编写的,也不是根据现有的一些权威文档编写的。因此,如果您最终想要与某些实现进行互操作,您可能必须查看实现的源代码以找出它们支持的内容。

例如,OpenSSL 在 crypto/pem/ 中定义这些 BEGIN 和 END 标记pem.h。以下是头文件的摘录,其中包含它们支持的所有 BEGIN 和 END 标签。

# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
# define PEM_STRING_X509         "CERTIFICATE"
# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
# define PEM_STRING_X509_CRL     "X509 CRL"
# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
# define PEM_STRING_PUBLIC       "PUBLIC KEY"
# define PEM_STRING_RSA          "RSA PRIVATE KEY"
# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
# define PEM_STRING_DSA          "DSA PRIVATE KEY"
# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
# define PEM_STRING_PKCS7        "PKCS7"
# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS   "PARAMETERS"
# define PEM_STRING_CMS          "CMS"

这些标签是一个开始,但您仍然需要研究实现如何对标签之间的数据进行编码。所有事情都没有一个正确答案。

For quite a long time, there was no formal specification of the PEM format with regards to cryptographic exchange of information. PEM is the textual encoding, but what is actually being encoded depends on the context. In April 2015, the IETF approved RFC 7468, which finally documents how various implementations exchange data using PEM textual encoding. The following list, taken directly from the RFC, describes the PEM format used for the following scenarios:

  1. Certificates, Certificate Revocation Lists (CRLs), and Subject
    Public Key Info structures in the Internet X.509 Public Key
    Infrastructure Certificate and Certificate Revocation List (CRL)
    Profile [RFC5280].
  2. PKCS #10: Certification Request Syntax [RFC2986].
  3. PKCS #7: Cryptographic Message Syntax [RFC2315].
  4. Cryptographic Message Syntax [RFC5652].
  5. PKCS #8: Private-Key Information Syntax [RFC5208], renamed to One
    Asymmetric Key in Asymmetric Key Package [RFC5958], and Encrypted
    Private-Key Information Syntax in the same documents.
  6. Attribute Certificates in An Internet Attribute Certificate
    Profile for Authorization [RFC5755].

According to this RFC, for the above scenarios you can expect the following labels to be within the BEGIN header and END footer. Figure 4 of the RFC has more detail, including corresponding ASN.1 types.

That's not the full story, though. The RFC was written by looking at existing implementations and documenting what they did. The RFC wasn't written first, nor was it written based on some existing authoritative documentation. So if you end up in a situation where you want to inter-operate with some implementation, you may have to look into the implementation's source code to figure out what they support.

For example, OpenSSL defines these BEGIN and END markers in crypto/pem/pem.h. Here is an excerpt from the header file with all the BEGIN and END labels that they support.

# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
# define PEM_STRING_X509         "CERTIFICATE"
# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
# define PEM_STRING_X509_CRL     "X509 CRL"
# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
# define PEM_STRING_PUBLIC       "PUBLIC KEY"
# define PEM_STRING_RSA          "RSA PRIVATE KEY"
# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
# define PEM_STRING_DSA          "DSA PRIVATE KEY"
# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
# define PEM_STRING_PKCS7        "PKCS7"
# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS   "PARAMETERS"
# define PEM_STRING_CMS          "CMS"

These labels are a start, but you still have to look into how the implementation encodes the data between the labels. There's not one correct answer for everything.

纸伞微斜 2024-10-30 01:15:47

更新了2015年的答案:由于用户已经回答了两次,在版主@royhowie删除答案之前:现在有定义 PEM 标头的 RFC 7468。下面的引用只是一小部分,你应该阅读实际的规范,它在互联网上的停留时间可能比 StackOverflow 长得多。

然而,@royhowie 删除了所有指向 RFC 的“仅链接”答案,除非它有一些文本。所以这里有一些文字:

<强>7。 PKCS #10 认证请求语法的文本编码

PKCS #10 认证请求使用以下编码进行编码
“证书请求”标签。编码数据必须是 BER (DER
强烈首选;请参阅附录 B)编码的 ASN.1
CertificationRequest 结构如 [RFC2986] 中所述。

-----开始证书请求-----
MIIBWDCCAQcCAQAwTjELMAkGA1UEBhMCU0UxJzAlBgNVBAoTHlNp​​bW9uIEpvc2Vm
c3NvbiBEYXRha29uc3VsdCBBQjEWMBQGA1UEAxMNam9zZWZzc29uLm9yZzBOMBAG
ByqGSM49AgEGBSuBBAAhAzoABLLPSkuXY0l66MbxVJ3Mot5FCFuqQfn6dTs+9/CM
EOLSwVej77tj56kj9R/j9Q+LfysX8FO9I5p3oGIwYAYJKoZIhvcNAQkOMVMwUTAY
BgNVHREEETAPgg1qb3NlZnNzb24ub3JnMAwGA1UdEweb/wQCMAAwDwYDVR0PAQH/
BAUDAwegADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgM/ADA8
AhxBvfhxPFfbBbsE1NoFmCUczOFAPEuQVUw3ZP69AhwWXk3dgSUsKnuwL5g/ftAY
dEQc8B8jAcnuOrfU
-----证书请求结束-----

图 9:PKCS #10 示例

“新证书请求”标签也被广泛使用。发电机
符合本文档必须生成“CERTIFICATE REQUEST”
标签。解析器可以将“新证书请求”视为等同于
“证书请求”。

Updated answer for 2015: As users have already answered twice, before moderator @royhowie deleted the answers: there is now RFC 7468 which defines the PEM headers. The following quote is only a small part, and you should read the actual spec, which will likely stay on the internet for far longer than StackOverflow will.

However @royhowie deletes every answer that points to the RFC as 'link only' unless it has some text. So here is some text:

7. Textual Encoding of PKCS #10 Certification Request Syntax

PKCS #10 Certification Requests are encoded using the
"CERTIFICATE REQUEST" label. The encoded data MUST be a BER (DER
strongly preferred; see Appendix B) encoded ASN.1
CertificationRequest structure as described in [RFC2986].

-----BEGIN CERTIFICATE REQUEST-----
MIIBWDCCAQcCAQAwTjELMAkGA1UEBhMCU0UxJzAlBgNVBAoTHlNpbW9uIEpvc2Vm
c3NvbiBEYXRha29uc3VsdCBBQjEWMBQGA1UEAxMNam9zZWZzc29uLm9yZzBOMBAG
ByqGSM49AgEGBSuBBAAhAzoABLLPSkuXY0l66MbxVJ3Mot5FCFuqQfn6dTs+9/CM
EOlSwVej77tj56kj9R/j9Q+LfysX8FO9I5p3oGIwYAYJKoZIhvcNAQkOMVMwUTAY
BgNVHREEETAPgg1qb3NlZnNzb24ub3JnMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/
BAUDAwegADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgM/ADA8
AhxBvfhxPFfbBbsE1NoFmCUczOFApEuQVUw3ZP69AhwWXk3dgSUsKnuwL5g/ftAY
dEQc8B8jAcnuOrfU
-----END CERTIFICATE REQUEST-----

Figure 9: PKCS #10 Example

The label "NEW CERTIFICATE REQUEST" is also in wide use. Generators
conforming to this document MUST generate "CERTIFICATE REQUEST"
labels. Parsers MAY treat "NEW CERTIFICATE REQUEST" as equivalent to
"CERTIFICATE REQUEST".

蓝眼睛不忧郁 2024-10-30 01:15:47

让您开始:据我所知,如果有一个部分是人类可读的(有文字和东西),这意味着操作人员可以知道相关的认证是什么、到期日期等,以便快速进行手动验证。所以你可以忽略它。

您需要解析 BEGIN-END 块之间的内容。

在里面,您将找到一个 Base64 编码的实体,您需要将其解码为字节。这些字节代表 DER 编码的证书/密钥/等。我不确定您可以使用哪些好的库来解析 DER 数据。

作为了解每个块内数据的测试,您可以将 BEGIN-END 块之间的内容粘贴到此站点,该站点在 JavaScript 中进行 ASN.1 解码:

http://lapo.it/asn1js/

虽然我不会将任何生产环境私钥粘贴到任何站点(尽管这似乎只是一个 JavaScript)。

Base64:http://en.wikipedia.org/wiki/Base64

DER:http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules

ASN.1:http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

To get you started: As far as I know, if there's a part that's human-readable (has words and stuff), that's meant for human operators to know what the certification in question is, expiry dates, etc, for a quick manual verification. So you can ignore that.

You'll want to parse what's between the BEGIN-END blocks.

Inside, you'll find a Base64 encoded entity that you need to Base64 decode into bytes. These bytes represent a DER encoded certificate/key/etc. I'm not sure what good libraries you could use for parsing the DER data.

As a test to understand what data is inside each block, you can paste what's between the BEGIN-END blocks to this site which does ASN.1 decoding in JavaScript:

http://lapo.it/asn1js/

Although I wouldn't go pasting any production environment private keys to any site (although that seems to be just a javascript).

Base64: http://en.wikipedia.org/wiki/Base64

DER: http://en.wikipedia.org/wiki/Distinguished_Encoding_Rules

ASN.1: http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

我也只是我 2024-10-30 01:15:47

我发现了一个关于此问题的旧线程。封装边界似乎没有“官方”标准格式,确定这一点的最佳方法是根据在 BEGIN 语句中找到的众所周知的关键字猜测内容。

正如 indiv 的回答,有关关键字的完整列表,请参阅 OpenSSL crypto/pem/pem.h 头文件。

I found an old thread regarding this issue. It looks like there is no "official" standard format for the encapsulation boundaries and the best way to determine this is by guessing the contents based on well-known keywords you find in the BEGIN statement.

As answered by indiv, for the full list of the keywords, refer to the OpenSSL crypto/pem/pem.h header file.

放飞的风筝 2024-10-30 01:15:47

我不确定它是否特定于 OpenSSL,但 PEM 加密格式可能就是您正在寻找的。

I am unsure if it's specific to OpenSSL, but the documentation for PEM Encryption Format may be what you're looking for.

眼泪淡了忧伤 2024-10-30 01:15:47

PEM文件格式在哪里指定?

没有一处地方。这取决于标准。您甚至可以创建自己的封装边界并在自己的软件中使用它们。

正如 @indiv 所说,OpenSSL 在 /crypto/pem/pem.h 中有一个相当全面的列表。

有人要求 PKIX 工作组提供一份像您在 2006 年要求的那样的列表。工作组拒绝了。请参阅 PEM 文件格式 rfc 草案请求

Where is the PEM file format specified?

There is no one place. It depends on the standard. You can even make up your own encapsulation boundaries and use them in your own software.

As @indiv stated, OpenSSL has a fairly comprehensive list at <openssl dir>/crypto/pem/pem.h.

Someone asked the PKIX Working Group to provide a list like you are asking for back in 2006. The working group declined. See PEM file format rfc draft request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文