翻译 RFC 4648: Base16、Base32 和 Base64 数据编码

LabMemNo003

每年都会有人尝试翻译 RFC 系列文档,为了能更好地迭代和组织所翻译的内容,我建立了一个 GitHub 仓库,希望有兴趣的人可以参与进来。翻译是个既耗时又费力的事情,因此我期望的是一种细水长流的模式,即使是几句话的翻译或调整,都可以通过 PR 或邮件的方式提交,慢慢地积累来完成这一项目。

https://github.com/dianbo-rfc/dianbo-rfc

另外,为了方便 RFC 文档的阅读,我试着建立了一个网站。网站的视觉效果应该会好些,使用了等宽字体,并且有中英对照;但毕竟是第一次进行网站开发,且使用的是最低配的服务器,响应时间、页面布局会有很多问题。

https://dianbo-rfc.cn/progress

下面的译文是发布此文章时的版本,未来可能更新的译文需要到 GitHub 或网站上阅读:







Network Working Group                                       S. Josefsson
Request for Comments: 4648                                           SJD
Obsoletes: 3548                                             October 2006
Category: Standards Track


                   Base16、Base32 和 Base64 数据编码

Status of This Memo

   This document specifies an Internet standards track protocol for the
   Internet community, and requests discussion and suggestions for
   improvements.  Please refer to the current edition of the "Internet
   Official Protocol Standards" (STD 1) for the standardization state
   and status of this protocol.  Distribution of this memo is unlimited.

Copyright Notice

   Copyright (C) The Internet Society (2006).

摘要

   此文档描述了经常使用的 base 64、base 32 和 base 16 编码方案。此外, 它
   还讨论了以下内容: 在编码数据中使用换行符、在编码数据中使用填充符、在
   编码数据中使用非字母表中的字符、不同编码字母表的使用、及规范编码。


























Josefsson                   Standards Track                     [Page 1]

RFC 4648                    Base-N Encodings                October 2006


目录

   1. 导言 ............................................................3
   2. 此文档中使用的约定 ..............................................3
   3. 各实现间的差异 ..................................................3
      3.1. 编码数据中的换行符 .........................................3
      3.2. 编码数据中的填充符 .........................................4
      3.3. 编码数据中非字母表中字符的解释 .............................4
      3.4. 字母表的选择 ...............................................4
      3.5. 规范编码 (Canonical Encoding) ..............................5
   4. Base 64 编码 ....................................................5
   5. 具有 "对 URL 和文件名安全的字母表" 的 Base 64 编码 ..............7
   6. Base 32 编码 ....................................................8
   7. 具有 "扩展十六进制的字母表" 的 Base 32 编码 ....................10
   8. Base 16 编码 ...................................................10
   9. 图解和示例 .....................................................11
   10. 测试样例 ......................................................12
   11. ISO C99 中的 Base64 编码的实现 ................................14
   12. 安全注意事项 ..................................................14
   13. 自 RFC 3548 以来的修改 ........................................15
   14. 致谢 ..........................................................15
   15. Copying Conditions ............................................15
   16. 参考文献 ......................................................16
      16.1. 前提类参考文献 ...........................................16
      16.2. 信息类参考文献 ...........................................16


























Josefsson                   Standards Track                     [Page 2]

RFC 4648                    Base-N Encodings                October 2006


1.  导言

   由于历史遗留原因, 有些环境只能使用 US-ASCII [1] 表示的数据, 而数据的
   Base 编码 (Base encoding) 经常被用在这种情况中。Base 编码也可以被用于
   不受历史遗留原因所限制的新应用中, 仅仅是因为它使得 "通过文本编辑器来
   操作对象" 成为可能。


   过去, 不同的应用程序具有不同的需求, 因此它们有时会以略微不同的方式来
   实现 Base 编码。如今, 有些协议规范有时会普遍地使用 Base 编码, 尤其是
   "base64", 但是却没有该编码的准确描述或参考文献。多用途互联网邮件扩展
   (MIME, Multipurpose Internet Mail Extensions) 经常被用作是 base64 的
   参考文献, 但是它没有考虑到换行符 (line-wrapping) 或非字母表中字符所造
   成的结果。此规范的目的是建立起通用的字母表及编码时的注意事项。这将有
   望减少其它文档中的歧义性, 从而实现更好的互操作性。




2.  此文档中使用的约定

      在此文档中, 关于关键词【必须】、【禁止】、【必要的】、【应当】、
      【不应】、【推荐的】、【可以】与【可选的】的解释, 见 [2] 中的描
      述。

3.  各实现间的差异

   这里, 我们将讨论过去的各 Base 编码实现之间的差异, 并在适当时, 规定了
   用于将来的具体的推荐行为。


3.1.  编码数据中的换行符

   MIME [4] 经常被用作是 base 64 编码的参考文献。但是, MIME 并没有定义
   "base 64" 本身, 而是定义了被用于 MIME 中的 "base 64 内容传输编码"
   ("base 64 Content-Transfer-Encoding")。其中, MIME 强制性限制了: 使用
   base 64 编码的数据, 其每行长度为 76 个字符。MIME 继承了隐私增强邮件
   (PEM, Privacy Enhanced Mail) [3] 中的编码, 并指出它 "实际上是相同的";
   但是, PEM 使用的每行长度为 64 个字符。MIME 和 PEM 的限制都是由于 SMTP
   中存在的限制所造成的。


   程序实现【禁止】向使用 base 编码的数据中添加换行符, 除非参考了此文档
   的其它规范, 有明确地指示 base 编码器: 在特定数量的字符后添加换行符。







Josefsson                   Standards Track                     [Page 3]

RFC 4648                    Base-N Encodings                October 2006


3.2.  编码数据中的填充符

   在某些情况下, 不需要或不用在 base 编码的数据中使用填充符 ("=")。在一
   般情况下, 当无法假设传输数据的大小时, 需要使用填充符来产生正确的编码
   数据。


   程序实现【必须】在编码数据的末尾包含适当的填充字符, 除非参考了此文档
   的其它规范另有明确规定。


   base64 和 base32 编码中的字母表使用了填充符, 见下面第 4 节和第 6 节的
   描述, 但是 base16 编码中的字母表不需要它, 见第 8 节。


3.3.  编码数据中非字母表中字符的解释

   Base 编码使用了一个特殊的、删减版的字母表来编码二进制数据。由于数据损
   坏或设计原因, base 编码的数据中可能存在非字母表中的字符。非字母表中的
   字符可能被用作 "隐蔽信道" ("covert channel"), 其中非协议的数据可能出
   于恶意目的而被发送。此外, 为了探索实现中的错误 (例如, 可能导致内存溢
   出攻击), 非字母表中的字符也可能会被发送。



   当程序实现在解释 base 编码的数据时, 若发现数据中包含 base 字母表外的
   字符, 程序实现【必须】拒绝编码数据, 除非参考了此文档的其它规范另有明
   确规定。这些规范可能会同 MIME 一样规定: 在解释数据时, 应当简单地忽略
   掉在 base 编码字母表以外的字符 ("在接受的内容上要放宽")。注意, 这意味
   着: 任何相邻的回车/换行 (CRLF) 均构成 "非字母表中字符", 并被忽略掉。
   此外, 这类规范【可以】将出现在编码数据末尾的填充符 "=" 认作是非字母表
   中的字符, 并将其忽略掉。如果在字符串的末尾发现了超出允许数量的填充字
   符 (例如, 一个 base 64 字符串以 "===" 结束), 则超出的填充字符【可以】
   被忽略。






3.4.  字母表的选择

   不同的应用对字母表中的字符有不同的需求。以下是一些需求, 用于确定应当
   使用哪个字母表:







Josefsson                   Standards Track                     [Page 4]

RFC 4648                    Base-N Encodings                October 2006


   o  由人类处理。字符 "0" 和 "O" 很容易混淆, 字符 "1"、"l" 和 "I" 也很
      容易混淆。在下面的 base32 字母表中, 没有字符 "0" (零) 和 "1" (一),
      根据情况, 一个解码器可能将 0 解释为 O, 并将 1 解释为 I 或 L 。(但
      是, 在默认情况下, 不应如此; 见前面的章节。)


   o  编码后的数据, 其结构要满足其它要求。对于 base 16 和 base 32 编码,
      这确定了使用大写或小写的字母表。对于 base 64 编码, 非字母表中的字
      符 (特别是 "/") 可能会在文件名和 URL 中出现问题。


   o  用作标识符。一些字符, 特别是 base 64 字母表中的 "+" 和 "/", 会被传
      统的文本搜索/索引工具视为分词符。


   没有能够满足所有的需求、被普遍接受的字母表。一个关于高度专业化变体的
   示例, 见 IMAP [8]。在此文档中, 我们记录并命名了一些当前正在被使用的字
   母表。


3.5.  规范编码 (Canonical Encoding)

   base 64 和 base 32 编码中的填充步骤, 如果没有被正确地实现, 将会导致编
   码后的数据出现不易察觉的改变。例如, 对于 base 64 编码, 如果它的输入仅
   为一个八位字节, 则使用到了第一个符号中所有 6 个比特位, 但是只使用了下
   一个符号中前 2 个比特位。遵循协议的编码器【必须】将扩充的比特位置零,
   这将在下文描述填充符时进步一说明。如果不保留这一特性, 则不存在对 base
   编码的规范表示, 且会出现: 多个 base 编码字符串被解码为相同的二进制数
   据。如果保留这一特性, 则能够保证规范编码。
   




   在一些环境中, 对于数据中的变动非常严格, 因此: 如果未将填充比特位置为
   零, 则编码器【可以】选择拒绝编码数据。与此相关的规范可能规定一个特殊
   的行为。


4.  Base 64 编码

   下文中对 base 64 编码的描述来自于 [3], [4], [5] 与 [6]。可以使用
   "base64" 来代称此编码方案。

   Base 64 编码被设计成: 在允许使用区分大小写的表示形式时, 它能够表示任
   意的八字节序列, 但是并不需要被人类可读。





Josefsson                   Standards Track                     [Page 5]

RFC 4648                    Base-N Encodings                October 2006


   编码使用了一个包含 US-ASCII 中的 65 个字符的字符子集, 其中的每个可打
   印字符能够表示 6 比特的数据。(额外的第 65 个字符是 "=", 其被用于表示
   需要特殊的处理)。

   编码的过程是将 "24 位组" 的多组输入比特, 表示为多个 "由 4 个编码字符
   构成" 的多个字符串。按照从左至右的处理顺序, 每 3 个 "8 位组" 的原始输
   入构成一个 "24 位组" 的编码输入。这些 "24 位组" 的输入将被视作由 4 个
   "6 位组" 的数据构成, 每一组都会被编码为 base 64 字母表中的单个字符。



   每个 6 位组的数据被用作 "64 个可打印字符的数组" 的索引。被索引所引用
   的字符置于输出字符串中。


                       表 1: Base 64 编码的字母表

        值 编码         值 编码         值 编码         值 编码
         0 A            17 R            34 i            51 z
         1 B            18 S            35 j            52 0
         2 C            19 T            36 k            53 1
         3 D            20 U            37 l            54 2
         4 E            21 V            38 m            55 3
         5 F            22 W            39 n            56 4
         6 G            23 X            40 o            57 5
         7 H            24 Y            41 p            58 6
         8 I            25 Z            42 q            59 7
         9 J            26 a            43 r            60 8
        10 K            27 b            44 s            61 9
        11 L            28 c            45 t            62 +
        12 M            29 d            46 u            63 /
        13 N            30 e            47 v
        14 O            31 f            48 w      (填充符) =
        15 P            32 g            49 x
        16 Q            33 h            50 y

   如果在数据的末尾, 可用于编码的数据少于 24 比特, 则需进行特殊的处理。
   使得在对数据的末尾编码时, 总是能够以完整的 "24 位组" 的编码方式结束。
   当输入比特组中的位数少于 24 比特时, 会在输入的右侧添加值为 0 的比特,
   以构成一个完整的 "6 位组"。接着使用字符 "=" 对数据的末尾进行填充。因
   为, 所有 base 64 编码的输入都是整数个八位字节, 所以只会出现一下情况:




   (1) 如果编码输入的最后部分的比特位数是 24 的整数倍; 则编码输出的最后
       部分的字符个数是 4 的整数倍, 且没有用字符 "=" 填充。




Josefsson                   Standards Track                     [Page 6]

RFC 4648                    Base-N Encodings                October 2006


   (2) 如果编码输入的最后部分的比特位数刚好是 8 位; 则编码输出的最后部分
       将会是: 2 个编码字符, 再后跟 2 个 "=" 填充符。


   (3) 如果编码输入的最后部分的比特位数刚好是 16 位; 则编码输出的最后部
       分将会是: 3 个编码字符, 再后跟 1 个 "=" 填充符。


5.  具有 "对 URL 和文件名安全的字母表" 的 Base 64 编码

   具有 "对 URL 和文件名安全的字母表" 的 Base 64 编码, 已经被用于 [12]。


   有些替换用的字母表, 建议使用 "~" 作为第 63 个字符。因为, 在一些文件系
   统的环境中, 字符 "~" 具有特殊的含义, 所以建议还是使用本节所描述的编码
   方案。剩余的未被 URI 所保留的字符是 ".", 但是在一些文件系统的环境中,
   不允许在一个文件名中使用多个 ".", 因此使得字符 "." 也没有吸引力。



   当在 URI [9] 中使用时, 填充字符 "=" 通常是被百分号编码的 (percent-
   encoded), 但是如果隐士地知道数据的长度, 则可以通过跳过填充符来避免这
   一情况; 见第 3.2 节。

   这里给出的编码方案可用 "base64url" 来代称。不应认为此编码与 "base64"
   编码相同, 且不应仅用 "base64" 来指代此编码。除非另有说明, 否则
   "base64" 指代的是前面章节中的 base 64 编码。


   此编码方案, 除了在第 62 个和第 63 个字符上有所区别, 从技术上而言与之
   前的相同, 如表 2 所示。




















Josefsson                   Standards Track                     [Page 7]

RFC 4648                    Base-N Encodings                October 2006


           表 2: "对 URL 和文件名安全的" Base 64 编码的字母表

        值 编码         值 编码         值 编码         值 编码
         0 A            17 R            34 i            51 z
         1 B            18 S            35 j            52 0
         2 C            19 T            36 k            53 1
         3 D            20 U            37 l            54 2
         4 E            21 V            38 m            55 3
         5 F            22 W            39 n            56 4
         6 G            23 X            40 o            57 5
         7 H            24 Y            41 p            58 6
         8 I            25 Z            42 q            59 7
         9 J            26 a            43 r            60 8
        10 K            27 b            44 s            61 9
        11 L            28 c            45 t            62 - (减号)
        12 M            29 d            46 u            63 _ (下划线)
        13 N            30 e            47 v
        14 O            31 f            48 w
        15 P            32 g            49 x
        16 Q            33 h            50 y      (填充符) =

6.  Base 32 编码

   下文中对 base 32 编码的描述来自于 (更正后的) [11]。可以使用 "base32"
   来代称此编码方案。

   Base 32 编码被设计成: 在需要使用不区分大小写的表示形式时, 它能够表示
   任意的八字节序列, 但是并不需要被人类可读。


   编码使用了一个包含 US-ASCII 中的 33 个字符的字符子集, 其中的每个可打
   印字符能够表示 5 比特的数据。(额外的第 33 个字符是 "=", 其被用于表示
   需要特殊的处理)。

   编码的过程是将 "40 位组" 的多组输入比特, 表示为多个 "由 8 个编码字符
   构成" 的多个字符串。按照从左至右的处理顺序, 每 5 个 "8 位组" 的原始输
   入构成一个 "40 位组" 的编码输入。这些 "40 位组" 的输入将被视作由 8 个
   "5 位组" 的数据构成, 每一组都会被编码为 base 32 字母表中的单个字符。
   当一个比特流通过 base 32 编码方式进行编码时, 必须假定该比特流的位序满
   足最高位优先。因此, 在比特流的第一个 8 位字节中, 第一个比特是最高位,
   第八个比特是最低位, 依此类推。










Josefsson                   Standards Track                     [Page 8]

RFC 4648                    Base-N Encodings                October 2006


   每个 5 位组的数据被用作 "32 个可打印字符的数组" 的索引。被索引所引用
   的字符置于输出字符串中。这些字符是从 US-ASCII 的数字和大写字母中选出,
   如下表 3 所示:


                       表 3: Base 32 编码的字母表

        值 编码         值 编码         值 编码         值 编码
         0 A             9 J            18 S            27 3
         1 B            10 K            19 T            28 4
         2 C            11 L            20 U            29 5
         3 D            12 M            21 V            30 6
         4 E            13 N            22 W            31 7
         5 F            14 O            23 X
         6 G            15 P            24 Y      (填充符) =
         7 H            16 Q            25 Z
         8 I            17 R            26 2

   如果在数据的末尾, 可用于编码的数据少于 40 比特, 则需进行特殊的处理。
   使得在对数据的末尾编码时, 总是能够以完整的 "40 位组" 的编码方式结束。
   当输入比特组中的位数少于 40 比特时, 会在输入的右侧添加值为 0 的比特,
   以构成一个完整的 "5 位组"。接着使用字符 "=" 对数据的末尾进行填充。因
   为, 所有 base 32 编码的输入都是整数个八位字节, 所以只会出现一下情况:




   (1) 如果编码输入的最后部分的比特位数是 40 的整数倍; 则编码输出的最后
       部分的字符个数是 8 的整数倍, 且没有用字符 "=" 填充。


   (2) 如果编码输入的最后部分的比特位数刚好是 8 位; 则编码输出的最后部分
       将会是: 2 个编码字符, 再后跟 6 个 "=" 填充符。


   (3) 如果编码输入的最后部分的比特位数刚好是 16 位; 则编码输出的最后部
       分将会是: 4 个编码字符, 再后跟 4 个 "=" 填充符。


   (4) 如果编码输入的最后部分的比特位数刚好是 24 位; 则编码输出的最后部
       分将会是: 5 个编码字符, 再后跟 3 个 "=" 填充符。


   (5) 如果编码输入的最后部分的比特位数刚好是 32 位; 则编码输出的最后部
       分将会是: 7 个编码字符, 再后跟 1 个 "=" 填充符。






Josefsson                   Standards Track                     [Page 9]

RFC 4648                    Base-N Encodings                October 2006


7.  具有 "扩展十六进制的字母表" 的 Base 32 编码

   下文中对 base 32 编码的描述来自于 [7]。可以使用 "base32hex" 来代称此
   编码方案。不应认为此编码与 "base32" 编码相同, 且不应仅用 "base32" 来
   指代此编码。此编码有被用于 NextSECure3 (NSEC3) [10]。



   此字母表具有一个 base64 和 base32 的字母表所缺少的特性, 即: 当对数据
   通过按位比较的方式进行排序时, 该字母表能保证编码后的数据具有同原始数
   据相同的排序顺序。

   此编码方案, 除了在字母表上有所区别, 其它方面与之前的相同。新的字母表
   如表 4 所示。

              表 4: "扩展十六进制的"  Base 32 编码的字母表

            值 编码         值 编码         值 编码         值 编码
             0 0             9 9            18 I            27 R
             1 1            10 A            19 J            28 S
             2 2            11 B            20 K            29 T
             3 3            12 C            21 L            30 U
             4 4            13 D            22 M            31 V
             5 5            14 E            23 N
             6 6            15 F            24 O      (填充符) =
             7 7            16 G            25 P
             8 8            17 H            26 Q

8.  Base 16 编码

   下文中的描述是原始的, 但是与先前的描述类似。本质上, Base 16 编码是标
   准的不区分大小写的十六进制编码, 且可以使用 "base16" 或 "hex" 来代称此
   编码方案。

   编码使用了一个包含 US-ASCII 中的 16 个字符的字符子集, 其中的每个可打
   印字符能够表示 4 比特的数据。

   编码的过程是将 "8 位组" (即八位字节) 的多组输入比特, 表示为多个 "由 2
   个编码字符构成" 的多个字符串。按照从左至右的处理顺序, 从原始输入中取
   出 "8 位组" 作为编码输入。这些 "8 位组" 的输入将被视作由 2 个 "4 位
   组" 的数据构成, 每一组都会被编码为 base 16 字母表中的单个字符。


   每个 4 位组的数据被用作 "16 个可打印字符的数组" 的索引。被索引所引用
   的字符置于输出字符串中。






Josefsson                   Standards Track                    [Page 10]

RFC 4648                    Base-N Encodings                October 2006


                       表 5: Base 16 编码的字母表

            值 编码         值 编码         值 编码         值 编码
             0 0             4 4             8 8            12 C
             1 1             5 5             9 9            13 D
             2 2             6 6            10 A            14 E
             3 3             7 7            11 B            15 F

   不同于 base 32 和 base 64 编码, 这里不需要特殊的填充符; 因为 base 16
   编码的最小单元是八位字节, 这在所有的数据中都能得到保证。

9.  图解和示例

   为了在二进制和 base 编码之间进行转换, 需要将输入存储在某一结构中, 并
   从中提取所需的输出。下图中所展示的 base 64 编码的例子, 来自于 [5]。


            +--first octet--+-second octet--+--third octet--+
            |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
            +-----------+---+-------+-------+---+-----------+
            |5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|5 4 3 2 1 0|
            +--1.index--+--2.index--+--3.index--+--4.index--+

   下图所展示的 base 32 编码的例子, 来自于 [7]。在 base-32 编码后的值中,
   每个连续的字符都表示: 原始的八位字节序列中的 5 个连续比特。因此, 每组
   "由 8 个编码字符构成" 字符串表示一个 "由 5 个八位字节构成" (40 比特)
   的序列。

                        1          2          3
             01234567 89012345 67890123 45678901 23456789
            +--------+--------+--------+--------+--------+
            |< 1 >< 2| >< 3 ><|.4 >< 5.|>< 6 ><.|7 >< 8 >|
            +--------+--------+--------+--------+--------+
                                                    <===> 8th character
                                              <====> 7th character
                                         <===> 6th character
                                   <====> 5th character
                             <====> 4th character
                        <===> 3rd character
                  <====> 2nd character
             <===> 1st character










Josefsson                   Standards Track                    [Page 11]

RFC 4648                    Base-N Encodings                October 2006


   下面有关 Base64 数据编码的示例来自于 [5] (已更正)。

      Input data:  0x14fb9c03d97e
      Hex:     1   4    f   b    9   c     | 0   3    d   9    7   e
      8-bit:   00010100 11111011 10011100  | 00000011 11011001 01111110
      6-bit:   000101 001111 101110 011100 | 000000 111101 100101 111110
      Decimal: 5      15     46     28       0      61     37     62
      Output:  F      P      u      c        A      9      l      +

      Input data:  0x14fb9c03d9
      Hex:     1   4    f   b    9   c     | 0   3    d   9
      8-bit:   00010100 11111011 10011100  | 00000011 11011001
                                                      pad with 00
      6-bit:   000101 001111 101110 011100 | 000000 111101 100100
      Decimal: 5      15     46     28       0      61     36
                                                         pad with =
      Output:  F      P      u      c        A      9      k      =

      Input data:  0x14fb9c03
      Hex:     1   4    f   b    9   c     | 0   3
      8-bit:   00010100 11111011 10011100  | 00000011
                                             pad with 0000
      6-bit:   000101 001111 101110 011100 | 000000 110000
      Decimal: 5      15     46     28       0      48
                                                  pad with =      =
      Output:  F      P      u      c        A      w      =      =

10.  测试样例

   BASE64("") = ""

   BASE64("f") = "Zg=="

   BASE64("fo") = "Zm8="

   BASE64("foo") = "Zm9v"

   BASE64("foob") = "Zm9vYg=="

   BASE64("fooba") = "Zm9vYmE="

   BASE64("foobar") = "Zm9vYmFy"

   BASE32("") = ""

   BASE32("f") = "MY======"

   BASE32("fo") = "MZXQ===="



Josefsson                   Standards Track                    [Page 12]

RFC 4648                    Base-N Encodings                October 2006


   BASE32("foo") = "MZXW6==="

   BASE32("foob") = "MZXW6YQ="

   BASE32("fooba") = "MZXW6YTB"

   BASE32("foobar") = "MZXW6YTBOI======"

   BASE32-HEX("") = ""

   BASE32-HEX("f") = "CO======"

   BASE32-HEX("fo") = "CPNG===="

   BASE32-HEX("foo") = "CPNMU==="

   BASE32-HEX("foob") = "CPNMUOG="

   BASE32-HEX("fooba") = "CPNMUOJ1"

   BASE32-HEX("foobar") = "CPNMUOJ1E8======"

   BASE16("") = ""

   BASE16("f") = "66"

   BASE16("fo") = "666F"

   BASE16("foo") = "666F6F"

   BASE16("foob") = "666F6F62"

   BASE16("fooba") = "666F6F6261"

   BASE16("foobar") = "666F6F626172"
















Josefsson                   Standards Track                    [Page 13]

RFC 4648                    Base-N Encodings                October 2006


11.  ISO C99 中的 Base64 编码的实现

   在 ISO C99 中有 Base64 编码与解码的实现, 该实现被认为是遵循了此 RFC
   中的所有建议, 可以从这里获取:

      http://josefsson.org/base-encoding/

   其中给出的代码不是必须的。

   由于工作流程相关的原因, 不能在此 RFC 中包含该代码 (见 RFC 3978 中第
   5.4 节)。

12.  安全注意事项

   在实现 base 编码与解码时, 需要注意: 不要引入会造成内存溢出攻击、或其
   它攻击的漏洞。解码器不应因无效输入而崩溃, 例如遇到了嵌入在数据中的字
   符 NUL (ASCII 0).


   在解码过程中, 如果选择忽略掉非字母表中的字符, 且没有 (按照建议) 拒绝
   掉整个编码数据, 则可能产生成一个导致信息 "泄露" 的隐蔽信道 (covert
   channel)。被忽略的字符也可以被用于其它的恶意目的, 例如: 规避字符串的
   判等、或出发实现中的 bug。未遵循推荐做法的应用, 应当弄清: 忽略非字母
   表中的字符, 这一行为背后的含义。类似的, 当以不区分大小写的方式来处理
   base 16 和 base 32 的字母表时, 字母大小写的变化可能被用于泄露信息、或
   导致字符串的判等失败。




   当使用填充符时, 需要考虑一些非有效比特位的安全性, 因为它们可能被滥用
   来泄露信息、或绕过字符串的判等、或触发实现中存在的问题。



   Base 编码从视觉上隐藏了那些的易被识别的信息, 例如密码, 但是它实际上并
   未提供任何的计算保密性。而这有可能会导致安全事故, 例如: 当用户在报告
   网络协议所交换的详细信息时 (可能是为了说明其它问题), 会意外地将密码泄
   露, 因为她并没有意识到 base 编码不能保护密码。




   Base 编码不会使文本熵增, 但是它确实增加了文本的长度, 并以特征概率分布
   (characteristic probability distribution) 的形式为密码分析过程
   (cryptanalysis) 提供了签名。





Josefsson                   Standards Track                    [Page 14]

RFC 4648                    Base-N Encodings                October 2006


13.  自 RFC 3548 以来的修改

   添加了 "使用扩展十六进制字母表的 base32" 的内容, 该编码被用于保留编码
   数据的排序顺序。

   参考了 IMAP, 以说明其中用到的特殊的 Base64 编码。

   修复了从 RFC 2440 复制过来的示例。

   添加了有关 "提供密码分析签名" 的安全注意事项。


   添加了测试样例。

   修复了笔误。

14.  致谢

   Several people offered comments and/or suggestions, including John E.
   Hadstate, Tony Hansen, Gordon Mohr, John Myers, Chris Newman, and
   Andrew Sieber.  Text used in this document are based on earlier RFCs
   describing specific uses of various base encodings.  The author
   acknowledges the RSA Laboratories for supporting the work that led to
   this document.

   This revised version is based in parts on comments and/or suggestions
   made by Roy Arends, Eric Blake, Brian E Carpenter, Elwyn Davies, Bill
   Fenner, Sam Hartman, Ted Hardie, Per Hygum, Jelte Jansen, Clement
   Kent, Tero Kivinen, Paul Kwiatkowski, and Ben Laurie.

15.  Copying Conditions

   Copyright (c) 2000-2006 Simon Josefsson

   Regarding the abstract and sections 1, 3, 8, 10, 12, 13, and 14 of
   this document, that were written by Simon Josefsson ("the author",
   for the remainder of this section), the author makes no guarantees
   and is not responsible for any damage resulting from its use.  The
   author grants irrevocable permission to anyone to use, modify, and
   distribute it in any way that does not diminish the rights of anyone
   else to use, modify, and distribute it, provided that redistributed
   derivative works do not contain misleading author or version
   information and do not falsely purport to be IETF RFC documents.
   Derivative works need not be licensed under similar terms.







Josefsson                   Standards Track                    [Page 15]

RFC 4648                    Base-N Encodings                October 2006


16.  参考文献

16.1.  前提类参考文献

   [1]   Cerf, V., "ASCII format for network interchange", RFC 20,
         October 1969.

   [2]   Bradner, S., "Key words for use in RFCs to Indicate Requirement
         Levels", BCP 14, RFC 2119, March 1997.

16.2.  信息类参考文献

   [3]   Linn, J., "Privacy Enhancement for Internet Electronic Mail:
         Part I: Message Encryption and Authentication Procedures", RFC
         1421, February 1993.

   [4]   Freed, N. and N. Borenstein, "Multipurpose Internet Mail
         Extensions (MIME) Part One: Format of Internet Message Bodies",
         RFC 2045, November 1996.

   [5]   Callas, J., Donnerhacke, L., Finney, H., and R. Thayer,
         "OpenPGP Message Format", RFC 2440, November 1998.

   [6]   Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
         "DNS Security Introduction and Requirements", RFC 4033, March
         2005.

   [7]   Klyne, G. and L. Masinter, "Identifying Composite Media
         Features", RFC 2938, September 2000.

   [8]   Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION
         4rev1", RFC 3501, March 2003.

   [9]   Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
         Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986,
         January 2005.

   [10]  Laurie, B., Sisson, G., Arends, R., and D. Blacka, "DNSSEC Hash
         Authenticated Denial of Existence", Work in Progress, June
         2006.

   [11]  Myers, J., "SASL GSSAPI mechanisms", Work in Progress, May
         2000.

   [12]  Wilcox-O'Hearn, B., "Post to P2P-hackers mailing list",
         http://zgp.org/pipermail/p2p-hackers/2001-September/
         000315.html, September 2001.




Josefsson                   Standards Track                    [Page 16]

RFC 4648                    Base-N Encodings                October 2006


作者地址

   Simon Josefsson
   SJD
   EMail: simon@josefsson.org














































Josefsson                   Standards Track                    [Page 17]

RFC 4648                    Base-N Encodings                October 2006


Full Copyright Statement

   Copyright (C) The Internet Society (2006).

   This document is subject to the rights, licenses and restrictions
   contained in BCP 78, and except as set forth therein, the authors
   retain all their rights.

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the procedures with respect to rights in RFC documents can be
   found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at
   ietf-ipr@ietf.org.

Acknowledgement

   Funding for the RFC Editor function is provided by the IETF
   Administrative Support Activity (IASA).







Josefsson                   Standards Track                    [Page 18]

阅读 687
1 声望
0 粉丝
0 条评论
你知道吗?

1 声望
0 粉丝
宣传栏