HOTP
HOTP(基于 HMAC 的一次性密码,RFC 4226)是 TOTP 的基于计数器的兄弟标准。TOTP 依据时钟递进,HOTP 则通过令牌和服务器在每次使用时同步递增的共享计数器来递进。HOTP 是 YubiKey OATH、旧式硬件令牌和部分服务器无法依赖时钟同步的银行流程的标准模式。
规范文件:RFC 4226, HOTP: An HMAC-Based One-Time Password Algorithm (2005).
URI 方案:Google Authenticator Key URI Format, 所有验证器达成共识的
关联规范:TOTP (RFC 6238), 基于 HOTP 构建的时间变体.
URI 方案:Google Authenticator Key URI Format, 所有验证器达成共识的
otpauth:// 方案. 关联规范:TOTP (RFC 6238), 基于 HOTP 构建的时间变体.
概述
HOTP 注册 QR 是以 hotp 为类型的 otpauth:// 方案 URL,携带共享 HMAC 密钥和两端必须保持同步的 计数器 值。格式:
otpauth://hotp/LABEL?secret=SECRET&issuer=ISSUER&counter=N&digits=N&algorithm=ALG- LABEL,
Issuer:Account,URL 编码。示例:YubiKey:alice@example.com。 - secret, 共享 HMAC 密钥,Base32 编码(RFC 4648 §6:A-Z、2-7)。
- counter, 起始计数器值。通常为
0,重新注册令牌时可从已知值恢复。 - issuer, 验证器应用中显示的服务名称。
- digits,
6(默认)或8。RFC 4226 §5.3 指定 6 位;8 位是常见扩展。 - algorithm, 实际上是
SHA1。RFC 4226 只定义 SHA1;SHA256/512 是后来附加的 RFC 6238 扩展。
HOTP vs TOTP, 选哪个
| 属性 | HOTP (RFC 4226) | TOTP (RFC 6238) |
|---|---|---|
| 递进依据 | 计数器(每次成功使用) | 时钟(每 30 秒) |
| 需要时钟同步 | 否 | 是,在 ~30 秒内 |
| 偏移时重同步 | 服务器接受接下来 N 个计数器值 | 服务器接受 ±1 窗口 |
| 典型场景 | YubiKey、旧式硬件令牌、离线银行 | 所有消费者 2FA, Google、Microsoft、1Password、Authy |
| 计数器重用 | 灾难性, 随时间泄露密钥 | 不适用 |
| 密钥泄露风险 | 未来所有代码可被预测 | 过去和未来所有代码可被预测 |
标准测试向量
RFC 4226 附录 D 提供了密钥 12345678901234567890(20 字节,Base32 GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ)的 6 位 HOTP 参考值:
| 计数器 | HOTP(6 位) |
|---|---|
0 | 755224 |
1 | 287082 |
2 | 359152 |
3 | 969429 |
4 | 338314 |
5 | 254676 |
6 | 287922 |
7 | 162583 |
8 | 399871 |
9 | 520489 |
计数器 0 时注册的最简 QR 载荷:
otpauth://hotp/Example:test?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=Example&counter=0实时 Base32 密钥验证器
与 TOTP 页面相同的验证器。HOTP 密钥使用相同的 Base32 字母表(RFC 4648 §6:A-Z、2-7)。在浏览器中运行,无服务器往返。
请输入密钥进行验证。
常见陷阱
- 计数器偏移。 如果用户按了令牌按钮但服务器未记录代码(网络故障、重复点击),令牌计数器超前于服务器计数器。服务器通过"重同步窗口"处理,尝试接下来 N 个计数器值后再拒绝。YubiKey 默认窗口为 ~3;高安全部署收窄至 1。
- 计数器重用是灾难性的。 永远不要接受同一计数器值两次。RFC 4226 §7.3 要求服务器拒绝任何等于或低于上次接受计数器的代码。
- 备份时的计数器导出。 某些导出 HOTP 条目的验证器应用只导出密钥而不导出当前计数器。导入新设备后计数器从 0 重新开始,与服务器不匹配,实际上注册已失效。TOTP 不受此影响;HOTP 在此处较脆弱。
- Base32 不是 Base64。 与 TOTP 相同的规则:含有
0、1、8、9、小写字母、+或/的密钥是 Base64,所有合规验证器都会拒绝。 - 实际上只有 SHA1。 RFC 4226 将 SHA1 定义为 HMAC 函数。大多数 HOTP 硬件令牌不实现 SHA256/SHA512。
- 位数参数常被忽略。 许多硬件令牌固定为 6 位,如果要求 8 位会静默截断。在 QR 印到实物卡片前先用目标硬件验证。
- 不要在同一 QR 中混用 HOTP 和 TOTP。 URI 方案通过
TYPE段(hotpvstotp)切换模式。一个密钥可以支持两种流程,但共享密钥意味着一个被攻破,两个都失效。
验证器应用兼容性
| 应用 / 令牌 | HOTP | SHA256/512 | 8 位 | 备注 |
|---|---|---|---|---|
| YubiKey Authenticator (iOS/Android/桌面) | 是 | 是 | 是 | HOTP 是 YubiKey OATH 的标准模式。完整 RFC 4226 支持。 |
| Google Authenticator | 是 | 忽略(仅 SHA1) | 忽略(仅 6 位) | 事实基准。HOTP 安全,但仅支持 6 位 SHA1。 |
| 1Password | 是 | 是 | 是 | 完整 RFC 支持。计数器随条目存储和导出。 |
| Bitwarden | 是 | 是 | 是 | 完整 RFC 支持。 |
| Microsoft Authenticator | 是 | 是 | 是 | 完整 RFC 支持。 |
| Authy | 否 | , | , | 近期版本已移除 HOTP,仅支持 TOTP。 |
| Duo Mobile | 否 | , | , | 使用自己的推送流程,仅 TOTP 备用。 |
| OATH 硬件令牌 (Feitian、Token2 等) | 是 | 因设备而异 | 因设备而异 | 标准硬件 HOTP 市场;除非数据表另有说明,始终为 6 位 SHA1。 |
另请参见
- /hotp-qr-code/, 带实时计数器和 Base32 验证的 HOTP 生成器。
- /standards/totp/, 时间变体(RFC 6238)。
- /totp-2fa-qr-code/, TOTP 生成器。
- /standards/, 返回标准索引。