TOTP Base32 与 Base64

TOTP Base32 vs Base64

我发现每个 TOTP 实现(甚至是 RedHat 的 FreeOTP)都使用 Base32 encoding/decoding 因为它是生成的秘密。 为什么不使用 Base64,因为 Base32 多使用了大约 20% space,而且它的主要优点是更易读?无论如何它都不会显示给用户生成。

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

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

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

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

之所以使用Base32是为了避免人为错误。与space.无关 RFC4226中之所以没有提到Base32,是因为它与私钥和HMAC以及token生成无关。 Base32 仅用于将私钥以人类可读的形式提供给人类。

如果有兴趣了解更多详情。

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

但是将这个秘密输入到像 Google 验证器这样的工具中并不容易。 好的,有一个二维码选项可以从网站上收集这个私钥,但这个功能并不总是可用。

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

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

一个重要而简单的原因以及 Base32 甚至存在的原因是它只使用 A-Z 大写字母(没有小写字母)和数字 2-7。没有 0189。 26 + 6 个字符 = 32.

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

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