TOTP 动态码

Base32 密钥算当前验证码,倒计时刷新,可校验并生成 otpauth 链接。

TOTP 就是把 RFC 4226 的 HOTP 计数器换成时间:T = floor((Unix 时间 − 起始时间) / 步长),再对 T 做 HMAC-SHA1,把摘要动态截断成 4 字节、对 10 的位数次方取模,就是手机上那串数字。密钥是一段随机字节,用 RFC 4648 的 Base32 写成可手抄的字符串。

Base32 只是编码,不是加密——它能防的是抄错,不是泄密,泄露的密钥和泄露的密码一样危险。算法默认 SHA-1:这是 RFC 6238 的强制项,所有验证器都认;SHA-256/SHA-512 属于可选项,本工具能算,但多数手机验证器不读这些参数。全部计算在浏览器本地完成,密钥不上传。

TOTP 动态码怎么用

  • 看当前令牌:填入 Base32 密钥即出现这一枚 6 位码,同一张卡上写明当前 UTC 时刻、剩余秒数(按你设的步长)以及计数器 T 的十进制与十六进制。页内自带一个逐秒刷新的定时器:标签页被切到后台时浏览器会把它节流,回到前台的第一次触发发现秒数已经跳过就立刻补画,所以显示的码始终对应当前时间,只是后台那几分钟里它不会逐秒动。
  • 调参数:位数直接切 6/8 按钮,步长、算法与校验容差收在「高级」折叠区里(步长限 5–300 秒,算法 SHA-1/256/512)。改动后 otpauth 链接里的 digits、period、algorithm 同步更新,「校验怎么判」那条也一并写明当前容差。
  • 调试与交付:「前后窗口表」折叠区算出上一步到后三步共 5 枚令牌,附各自的计数器 T;校验面板贴入验证码即判定,命中会写明在第几步、不命中给出本机此刻应有的令牌与时钟偏差估计(先在容差内找,找不到再扩到 ±10 步共 21 个窗口)。最后把 otpauth:// 链接那一整行交给对方——本页没有复制按钮,选中那一行自行复制;二维码功能尚未上线。

常见问题

计数器 T 是怎么变成那串数字的?

默认步长 30 秒、起点是 Unix 纪元。对 T 做 HMAC-SHA1,再把 20 字节的摘要动态截断成 4 字节(偏移取摘要最后一字节的低 4 位,最高位抹掉保证是 31 位正整数),对 10 的位数次方取模,就是手机上那串数字。

为什么我的码总和对不上?

九成是时钟漂移。TOTP 两边各自读本地时间算 T,只要手机和服务器差过半个步长就会落在不同窗口;RFC 6238 建议校验端最多放行 1 个步长的延迟,也就是 ±30 秒。用本页的 ±1 步容差和前后窗口表可以确认是不是只差一步,然后去同步系统时间(NTP),或按校验面板给出的偏差估计调整。

密钥为什么要写成 Base32?

因为密钥本质是随机字节,直接打印会撞上不可显示字符,人工抄写更容易错。RFC 4648 的 Base32 只用 32 个大写字母数字(A–Z、2–7),刻意排除 0/1/8/9 以及 I/O,读音和字形都不易混淆;otpauth 链接里还要求去掉 = 补位。本工具读密钥时容忍小写、空格和多余的 =。

改了位数或步长,为什么别的验证器不认?

digits、period、algorithm 都是双方必须一致的约定,RFC 里的默认值是 6 位、30 秒、SHA-1。你改成 8 位或 60 秒,自己两边能对上,但 Google Authenticator 这类 App 会忽略 otpauth 链接里的这些参数,始终按 6 位、30 秒、SHA-1 计算,于是永远不一致。除非两端都由你控制,否则别动默认值。

对应功能编号 #42无需安装,手机端同样可用按 Ctrl + K 换工具