我发现每个TOTP实现(甚至是RedHat的FreeOTP)都使用Base32编码/解码来生成它的 secret 。
为什么不使用Base64,因为Base32会占用大约20%以上的空间,而它的主要优点是它更易于阅读?无论如何,它不会显示给用户。
尽管实现中的每个注释都说,其实现遵循RFC6238/RFC4226,但我在RFC文档中找不到有关Base32的任何内容。
出于传输的数据安全性考虑,将其转换为Base32或Base64显然很有意义,但是为什么不只使用Base64呢?
最佳答案
使用Base32的原因是为了避免人为错误。它与空间无关。
RFC4226中未提及Base32的原因是,它与私钥,HMAC和 token 生成无关。
Base32仅用于以人类可读的形式将私钥传递给人类。
如果有兴趣,请提供更多详细信息。
TOTP中的私钥应为20字节(160位)的 secret 。
私钥与HMAC-SHA1一起使用来对时期计数器进行编码。
从生成的160位HMAC中提取 token 。
但是要将此 secret 输入到Google Authenticator之类的工具中并不容易。
好的,可以选择QR码从网站收集此私钥,但是此功能并非始终可用。
因此,当您必须输入此私钥时,您将以Base32格式与用户共享,即 key 被编码为可生成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。
关于java - TOTP Base32与Base64,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50082075/