TOTP(一次性密码)生成器

通过 Base32 格式的 TOTP 密钥,在浏览器本地生成与 Google Authenticator 等应用相同的 6 位一次性密码(RFC 6238)。密钥绝不会被发送到服务器。

本工具绝不会将密钥发送至任何服务器。Base32 解码与 HMAC 计算均在您的浏览器内(Web Crypto API)完成,因此可以放心输入身份验证信息。

关于 TOTP 算法

TOTP(基于时间的一次性密码)是 RFC 6238 中定义的、基于时间生成一次性密码的算法。它将共享密钥与当前时间转换为按固定间隔递增的计数器,再使用与 HOTP(RFC 4226)相同的动态截断算法推导出数字验证码。

HMAC 算法 可选择 SHA-1(默认)、SHA-256 或 SHA-512
验证码位数 6 位(与 Google Authenticator 等主流双重验证应用相同的标准位数)
更新周期 每 30 秒切换为新的验证码

什么是 TOTP(一次性密码)

TOTP(Time-based One-Time Password)是在账号密码之外再要求一道确认的双因素认证(2FA)中使用的、每30秒切换一次的6位一次性代码。它由事先登记的名为“密钥(secret)”的共有密钥与当前时刻组合计算得出,因此服务器与手中的认证应用无需通信也能同时得出相同的代码。Google Authenticator、Microsoft Authenticator、Authy 等主要认证应用均遵循 RFC 6238 这一共通规格。

本工具只需输入 2FA 登记时显示在二维码下方的“设置密钥”(Base32 形式的 secret),即可在浏览器内重现与认证应用相同的6位代码。密钥的 Base32 解码与 HMAC 计算全部由 Web Crypto API 完成,绝不会发送至服务器。可用于认证应用的重新设置、代码的核验,以及多设备上的动作确认等。

TOTP 代码的生成方法

  1. 输入密钥 把 2FA 登记时发放的 Base32 形式设置密钥(例:JBSWY3DPEHPK3PXP)粘贴到“密钥”栏。
  2. 确认哈希算法 多数服务使用 SHA-1;若不一致,请切换为 SHA-256 或 SHA-512 试试。
  3. 确认显示的6位代码 输入的同时会自动计算与当前时刻对应的代码,并连同剩余秒数的进度条一起显示。
  4. 按需复制 可用“复制”按钮把代码复制到剪贴板。请避开临近切换的时刻使用。

用好本工具的小技巧

  • 密钥就是首次注册双重验证(2FA)时,二维码下方显示的“设置密钥”字符串。如果您已在手机验证器应用中注册过,只需在此工具中输入相同的密钥即可核对验证码是否一致。
  • 部分服务采用的哈希算法并非 SHA-1(而是 SHA-256 或 SHA-512)。如果生成的验证码与实际应用不一致,请尝试切换算法再试。
  • 验证码每 30 秒自动更新一次,进度条可以直观显示剩余时间。请注意,如果在即将切换前复制验证码,可能在送达验证方之前就已失效。
  • 关闭浏览器标签页后,密钥会被彻底丢弃,不会保存在任何地方。如果需要作为备份保留,请另行将密钥本身保存在密码管理器等安全的地方。

TOTP 生成器派上用场的场景

2FA 应用的动作确认与迁移

在因换机而更换认证应用之前,可先用本工具核验留存的密钥是否正确,而不必到新设备上才发现问题。

开发、测试环境的登录确认

为自家服务实现 2FA 时,可随时由测试账号的密钥生成代码,用于认证逻辑的动作确认。

备份用密钥的验证

可在不打开手机认证应用的情况下,快速确认保存在密码管理器等处的密钥是否仍能正常工作。

账号整体的安全强化

若在 TOTP 之外还想重新审视登录密码本身的强度,也请使用密码生成或易记密码短语生成。

与哈希值的确认一并使用

若与 TOTP 一样对 HMAC 或哈希函数的原理感兴趣,欢迎用SHA-256 哈希计算尝试作为基础的哈希计算。

TOTP 相关术语集

TOTP(Time-based One-Time Password)
使用由当前时刻算出的计数器生成一次性密码的方式(RFC 6238)。每隔一定周期(通常30秒)代码会自动切换。
HOTP(HMAC-based One-Time Password)
TOTP 的前身规格(RFC 4226)。以“每次使用便前进一格的计数器”而非时刻来生成代码。
密钥(共有密钥)
服务方与用户认证应用双方共同持有的秘密密钥。在 2FA 登记时以 Base32 形式的字符串发放,由它与时刻计算出代码。
双因素认证(2FA)
在密码(知识要素)之外,再结合智能手机认证应用等(持有要素)确认的登录方式。即便一方泄露,也更易防止非法登录。
时间步长(更新周期)
TOTP 代码切换为新值的间隔。RFC 6238 的默认值为30秒,多数服务与认证应用直接沿用该值。
Base32
仅用英文大写字母(A~Z)与数字(2~7)共32种字符来表示字节序列的编码方式。TOTP 的密钥以这种可读性高的形式发放。
动态截断(Dynamic Truncation)
从 HMAC 计算结果(较长的字节序列)中按规则取出4个字节并转换为6位数值的处理。是 RFC 4226 定义的 HOTP・TOTP 共通算法。

常见问题

是的。Base32 解码与 HMAC 计算全部在浏览器内通过 Web Crypto API 执行,绝不会发送至服务器。您可以通过监控网络通信来确认输入的密钥并未被发送出去。

这可能是哈希算法不一致(多数服务使用 SHA-1,但部分服务使用 SHA-256 或 SHA-512),或设备时间存在偏差所致。请先尝试切换算法,如果仍然不一致,请检查设备的时间设置(自动时间同步)。

通常认为 TOTP 更安全。短信验证码存在因电话号码被劫持(SIM 卡交换诈骗)而被第三方截获的风险,而 TOTP 完全在设备本地完成运算,不会受到此类攻击的影响。

多数服务在首次设置双重验证时会发放“恢复代码”。如果连密钥本身也遗失了,则需要通过服务方的账户找回流程(身份验证)重新设置双重验证。
工具君

闲话 ― 双重验证为何最终定格为“6 位数”

制定 TOTP 规范(RFC 6238)的 OATH(开放身份验证倡议组织)直接沿用了 HOTP(RFC 4226)的动态截断算法,并将验证码的位数交由各实现自行决定。之所以 6 位成为事实上的行业标准,主要是因为 Google Authenticator 在 2010 年的初始实现中采用了这一位数,此后众多服务和库都纷纷效仿。

6 位数字也恰好是一个绝妙的平衡点。一百万种组合(10 的 6 次方)再加上短短 30 秒的有效期,使得暴力破解在现实中几乎不可能实现;而位数再多则会让用户难以记忆和手动输入。多数短信验证码同样采用 6 位并非巧合,而是整个“短时效、一次性数字验证码”这一品类共同收敛出的经验法则。

TOTP 的前身 HOTP(RFC 4226,2005 年)采用“计数器”方式,每使用一次验证码就必须将计数器递增一次。然而由于用户经常忘记操作,或者设备与服务器的计数器发生偏差,运维问题频发。因此 2011 年制定的 TOTP 改用任何人都能参照的统一基准——“当前时间”,大幅简化了运维流程。