9

我发现每个 TOTP 实现(甚至 RedHat 的 FreeOTP)都使用 Base32 编码/解码来生成秘密。为什么不使用 Base64,因为 Base32 使用了大约 20 % 的空间,而且它的主要优点是它更易于人类阅读?无论如何,它不会向用户显示生成。

虽然实现中的每条评论都说,它的实现遵循RFC6238 / RFC4226,但我在 RFC 文档中找不到关于 Base32 的任何内容。

由于传输数据的安全性,将其转换为 Base32 或 Base64 显然是有意义的,但为什么不直接使用 Base64 呢?

4

2 回答 2

13

使用 Base32 的原因是为了避免人为错误。它与空间无关。 RFC4226 中没有提到 Base32 的原因是因为它与私钥和 HMAC 以及令牌生成无关。Base32 仅用于以人类可读的形式将私钥传递给人类。

如果有兴趣,请提供更多详细信息。

TOTP 中的私钥应该是一个 20 字节(160 位)的密钥。私钥与 HMAC-SHA1 一起用于对纪元时间计数器进行编码。从生成的 160 位 HMAC 中提取令牌。

但是要将这个秘密输入到像 Google Authenticator 这样的工具中并不容易。好的,可以选择从网站收集此私钥的 QR 码,但此功能并不总是可用。

因此,当您必须输入此私钥时,您以 Base32 格式与用户共享,即密钥被编码为生成 Base32 字符串。

那么为什么在这种情况下 Base32 比 Base64 更好。

Base32 存在的一个重要且简单的原因是它仅使用 AZ 大写字母(没有小写字母)和数字 2-7。没有 0189。26 + 6 个字符 = 32。

没有小写字母,也没有数字 0189,因此“i”“l”“I”和“1”不会混淆。只有I。B和8之间的混淆,0和O也被消除了。

如果输入了 0,则可以将其视为 O。A 1 作为 I 等。工具是否尝试自动更正,或者我的偏好,只是告诉用户无效输入是个人喜好问题。但很明显,人为错误对字符串的非唯一解释显着减少。Base64 并非如此。
上述所有大小写和数字混淆的问题都适用于 Base64。

于 2019-08-02T11:38:58.897 回答
1

我相信这只是一个历史背景。一开始有人选择了Base32,一个工具变得流行起来,后代使用相同的编码来遵守。

我还看到很多使用十六进制格式的实现,提供的 RFC6238 中的示例也使用十六进制。

于 2018-05-25T12:01:22.623 回答