TOTP Base32与Base64

时间:2018-04-28 23:50:23

标签: java base64 one-time-password base32

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

虽然实现中的每条评论都说明其实现遵循Collectors.joining(CharSequence) / RFC6238,但我无法在RFC文档中找到关于base32的任何内容。

由于通过传输实现数据安全,将它转换为Base32或Base64显然是有意义的,但为什么不使用Base64呢?

2 个答案:

答案 0 :(得分:1)

我认为这只是一个历史背景。 最初的某个人选择了Base32,一个工具变得流行,后代使用相同的编码来遵守。

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

答案 1 :(得分:1)

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

有兴趣的更多详细信息。

TOTP中的私钥应该是20字节(160位)的秘密。 私钥与HMAC-SHA1一起使用来编码时期计数器。 从生成的160位HMAC中提取令牌。

但是要将此秘密输入到Google身份验证器之类的工具中并不容易。 好的,可以选择QR码从网站收集此私钥。 但是此功能并不总是可用。

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

所以在这种情况下,为什么BASE32比base64更好。

一个重要而简单的原因以及BASE32为何存在。 是仅使用A-Z大写字母(不使用小写字母)和数字2-7。 0189号 26 + 6个字符= 32。

没有小写字母,也没有0189,因此ilI1不会引起混淆。只有我 B和8 0以及O的混乱也被消除了。

要点是,如果输入0,则可以将其视为O。将1视为I等。 这些工具是尝试自动更正还是我的偏爱,只是告诉用户无效的输入是一个品味问题。但是很明显,人为错误对字符串的非唯一解释大大减少了。 base64并非如此。
以上所有带有大小写和数字混淆的问题都适用于base64。