TOTP 与 HOTP:一次性验证码背后的两种算法
为什么值得花两分钟搞懂
验证码"突然不对"这类问题,九成根子在 TOTP 的时间机制上。懂一点原理,排查就有方向。
TOTP:按时间换码
TOTP(Time-based One-Time Password,RFC 6238)的输入是两样东西:密钥 + 当前时间。
- 绑定账户时,网站把一段密钥以二维码交给你,FreeOTP 存进手机。
- 之后每次出码,App 用密钥和当前时间算出一个 6 位数,每 30 秒换一代。
- 网站服务端拿着同样的密钥和自己的时钟算同一个数。两边对上,验证通过。
推论:手机时钟和服务器时钟必须大致一致。多数服务端容忍前后各一个 30 秒窗口,手机时间偏差超过一分钟,码就会一直错。
HOTP:按次数换码
HOTP(HMAC-Based One-Time Password,RFC 4226)把"时间"换成"计数器":
- 每生成一次码,计数器加一,下一个码跟着变。
- 码不会自动过期——不生成、不使用,它就一直有效。
- 常见于硬件令牌和企业部署(如 FreeIPA 管理的令牌),个人网站用得少。
两者对使用者的差别
| 维度 | TOTP | HOTP |
|---|---|---|
| 换码时机 | 每 30 秒自动换 | 每使用一次换 |
| 有效期 | 窗口过后作废 | 不用就不过期 |
| 时钟敏感 | 敏感 | 不敏感 |
| 常见场景 | 网站 2FA | 企业令牌 / 硬件钥匙 |
FreeOTP 支持哪些哈希
令牌可用 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 五种哈希算法,位数与有效期也可按服务端要求调整——不过个人网站基本都用默认值(SHA-1、6 位、30 秒),手动改参数通常只出现在自托管场景。