跳到主要内容

2. General Considerations (一般考虑)

文本编码以包含 "-----BEGIN "、一个标签和 "-----" 的行开始, 并以包含 "-----END "、一个标签和 "-----" 的行结束。在这些行之间 (或称为 "封装边界" (encapsulation boundaries)), 是根据 [RFC4648] 第 4 节进行 base64 编码的数据。(PEM [RFC1421] 将这些数据称为 "封装文本部分" (encapsulated text portion)。) 封装边界之前的数据是允许的, 解析器在处理此类数据时不能出现故障。此外, 解析器应该忽略空白和其他非 base64 字符, 并且必须处理不同的换行约定。

编码的数据类型根据 "-----BEGIN " 行 (前封装边界 (pre-encapsulation boundary)) 中的类型标签进行标记。例如, 该行可能是 "-----BEGIN CERTIFICATE-----" 以指示内容是 PKIX 证书 (详见下文)。生成器必须在 "-----END " 行 (后封装边界 (post-encapsulation boundary)) 上放置与相应 "-----BEGIN " 行相同的标签。标签在形式上是区分大小写的、大写的, 并且由零个或多个字符组成; 它们不包含连续的空格或连字符减号 (hyphen-minuses), 也不包含两端的空格或连字符减号。如果标签不匹配, 解析器可以忽略后封装边界中的标签而不是发出错误信号: 一些现有的实现要求标签匹配; 其他的则不要求。

"BEGIN" 或 "END" 与标签之间恰好有一个空格字符 (SP)。封装边界两端恰好有五个连字符减号 (也称为短横线) 字符 ("-"), 不多不少。

标签类型意味着编码的数据遵循指定的语法。解析器必须优雅地处理不符合要求的数据。然而, 在本文档之前, 并非所有解析器或生成器的行为都是一致的。符合标准的解析器可以将内容解释为另一种标签类型, 但应该了解安全考虑部分中讨论的安全影响。本文档中描述的标签标识的容器格式不特定于任何特定的密码算法, 这一特性与算法敏捷性 (algorithm agility) 一致。这些格式使用 ASN.1 AlgorithmIdentifier 结构, 如 [RFC5280] 第 4.1.1.2 节所述。

与传统的 PEM 编码 [RFC1421]、OpenPGP ASCII armor 和 OpenSSH 密钥文件格式不同, 文本编码不定义或允许将头部 (headers) 与数据一起编码。前封装边界和 base64 数据之间可以出现空白区域, 但生成器不应该发出任何此类空白。(对这个空白区域的规定是对 PEM 的一种回溯, PEM 定义了一个 "封装头部部分" (encapsulated header portion)。)

实现者需要意识到, 现有的解析器在空白处理上存在相当大的差异。在本文档中, "空白" (whitespace) 是指在排版中表示水平或垂直空间的任何字符或一系列字符。在 US-ASCII 中, 空白是指 HT (0x09)、VT (0x0B)、FF (0x0C)、SP (0x20)、CR (0x0D) 和 LF (0x0A); "空格" (blank) 是指 HT 和 SP; 行用 CRLF、CR 或 LF 分隔。常见的 ABNF 产生式 WSP 与 "空格" (blank) 一致; 一个新的产生式 W 用于 "空白" (whitespace)。第 3 节中的 ABNF 特定于 US-ASCII。由于这些文本编码可以在许多不同的系统以及长期档案存储介质 (如纸张或雕刻) 上使用, 实现者在不严格限于 US-ASCII 的环境中生成或解析这些格式时, 应该使用规则的精神而不是字面意思。

大多数现有的解析器会忽略行尾的空格; 行开头或 base64 编码数据中间的空格的兼容性要差得多。这些观察结果在图 1 中得到了体现。最宽松的解析器实现根本不是面向行的, 并且会接受封装边界之外的任何空白混合 (见图 2)。这种宽松的解析可能会冒着接受本来不打算接受的文本的风险 (例如, 因为该文本是一个片段或示例)。

生成器必须换行 base64 编码的行, 使得每行恰好包含 64 个字符, 除了最后一行, 它将编码剩余的数据 (在 64 字符行边界内), 并且它们不能发出多余的空白。解析器可以处理其他行大小。这些要求与 PEM [RFC1421] 一致。

文件可以包含多个文本编码实例。例如, 当文件包含多个证书时会使用这种情况。实例是有序的还是无序的取决于上下文。