TOTP 动态口令是什么:二步验证原理与离线生成验证码

30 秒变一次的那 6 位数,到底是怎么算出来的

登录 GitHub、公司 VPN 或交易所时,除了密码还要再填一个"每 30 秒变一次"的 6 位数字——这就是 TOTP(Time-based One-Time Password,基于时间的一次性口令),也是各类验证器 App(Google Authenticator、微软 Authenticator 等)背后的通用标准。

这篇用 NBTools 的TOTP 工具讲清楚它的原理与用法:密钥从哪来、30 秒窗口是什么意思、算法和位数怎么选,以及"验证码总是对不上"时该查什么。密钥与验证码只在浏览器本地计算,不上传、不保存

怎么用:填密钥,看码和倒计时

  1. 粘贴 Base32 密钥:形如 JBSWY3DPEHPK3PXP 的一串字母数字(下面会讲它从哪来)。
  2. 确认参数:算法默认 SHA1、位数默认 6 位、周期默认 30 秒——绝大多数网站用的就是这套默认值。
  3. 点"获取验证码":下方显示当前 6 位口令与剩余有效秒数,到点自动刷新下一个。
  4. 需要停止时点"停止"即可。

密钥与验证码只在本地内存中生成,不会上传也不会被保存,刷新页面即清除。

原理:把"密钥 + 当前时间"算成一个数

TOTP 的核心可以用一句话概括——把共享密钥和"当前时间步长"一起做 HMAC 运算,再截断成 6 位数字

  • 时间步长:用当前 Unix 时间除以周期(默认 30 秒)并向下取整,得到一个不断递增的计数器。
  • HMAC 运算:用密钥对这个计数器做 HMAC 哈希(默认 SHA1)。
  • 动态截断:从哈希结果中取一段,转成十进制,再取末尾 6 位(或 8 位)。

因为输入里含有时间,所以每过 30 秒结果就自动变化;因为服务器持有同一个密钥、用同一个时间基准算同一个式子,所以它算出的数字和你的一致——这就是不需要网络同步验证码的原因。

三个参数怎么选

参数可选值默认值什么时候要改
算法SHA1 / SHA256 / SHA512SHA1绝大多数站点用 SHA1;少数安全要求高的服务会指定 SHA256/SHA512
位数6 位 / 8 位6 位按服务端要求,8 位多见于部分金融与企业系统
周期任意秒数30 秒默认 30;个别系统用 60 秒

这三个参数必须和服务端完全一致,只要有一个对不上,算出来的码就是错的。它们通常已经写在你绑定二步验证时看到的密钥或配置说明里。

Base32 密钥从哪来

开启二步验证时,网站一般会显示一个二维码,同时提供"无法扫描?手动输入密钥"的链接,点开看到的那串就是 Base32 密钥。如果只有二维码扫不到,可以用任意二维码识别工具先把内容读出来,其中的 secret= 字段值即为密钥。

安全提醒:这个密钥等同于你的第二重密码,不要截图发给别人、不要粘贴到不可信的网站。本工具仅在本地使用且不保存,但仍建议你只在自己设备上操作。

验证码对不上?先查这三点

  1. 设备时间不同步(最常见):TOTP 依赖时间,若本机时间偏差超过一个周期,算出的码就和服务器对不上。请把系统时间设为自动同步。
  2. 参数不一致:算法、位数、周期任一项与服务端不同都会失败,回头核对默认值是否被改过。
  3. 密钥复制有误:Base32 密钥不含数字 0/1/8/9,注意别把字母 O 与数字 0 看混,也不要带入空格。

另外,临近刷新边界(剩余 1–2 秒)时输入,可能在你提交时刚好失效——看到剩余时间不多时,等下一个码再填。

常见问题

这个工具能替代验证器 App 吗

它更适合临时查看、应急取码或验证密钥是否正确。因为密钥需要每次手动粘贴、且不会保存,日常长期使用仍是安装验证器 App 更方便。

密钥会上传或保存吗

不会。密钥与验证码完全在浏览器本地计算,不上传服务器、不写入本地存储,刷新页面即清除。

为什么验证码每 30 秒就变一次

因为 TOTP 把"当前时间除以周期"作为运算输入,每跨过一个 30 秒的时间步长,输入就改变,输出自然变化。周期可在工具里改,但必须与服务端一致。

提示生成失败怎么办

通常是密钥不是合法的 Base32 字符串。请去掉空格、确认没有把字母 O/I 误当数字 0/1,并完整复制整串密钥。

一个密钥能用在多个网站吗

不建议。每个网站应绑定各自独立的密钥,共用会让一个站点泄露时牵连其它账号。

相关工具

作者:NBTools · 更新于 2026年9月19日 · 阅读约 5 分钟