TOTP Base32 与 Base64

Let*_*eth 9 java base64 one-time-password base32

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

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

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

phi*_*ady 10

使用 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。