← 返回文章列表

两步验证到底防什么:TOTP 原理与安全边界

口令安全入门

TOTP 是什么

TOTP(基于时间的一次性口令)的核心很朴素:服务端和你的验证器 App 共享一个种子密钥,双方用「当前时间步长(通常 30 秒)+ HMAC-SHA1」算出同一串 6 位数字。服务器只要比对是否相等即可。

它到底防什么

2FA 防的是密码泄露或撞库:攻击者即使拿到你的密码,没有种子密钥也生成不了下一步的动态码。但它不防实时钓鱼——中间人可以把你刚输入的动态码立刻转发到真网站。

三种 2FA 强度对比

方式强度弱点
短信验证码弱可被 SIM 交换、信号拦截、运营商内部人员获取
TOTP 验证器 App中不绑定域名,易被实时钓鱼转发
硬件密钥 / Passkey(WebAuthn)强绑定域名,钓鱼无法重放;需设备支持

使用建议

  1. 优先级:硬件密钥或 Passkey 最好,其次 TOTP App;短信验证码只作为兜底;
  2. 保存恢复码:离线打印或密码管理器存一份,防止丢手机后锁死账号;
  3. 分开存放:不要把 TOTP 种子和主密码存在同一处(别让密码管理器既存密码又存动态码还同步到同一云);
  4. 时间校准:验证失败先确认设备时间准确,时间漂移会让动态码对不上。

种子密钥与二维码

开通 2FA 时看到的二维码是 otpauth:// 链接,其中种子用 Base32 编码。截图保存等于泄露种子,请用支持加密导出的验证器。

动手试试

生成强随机种子:密码生成器、哈希计算。

接入 TOTP 的实操细节

TOTP 的标准流程并不复杂(共享密钥 + 时间片 HMAC 取模),但工程细节决定安全性:

  1. 密钥要求:使用至少 160 位随机字节,用 Base32 展示给用户;密钥只在绑定时展示一次,之后加密存储且不可再明文读出;
  2. 时间对齐:服务端应接受前后各一个时间片(共三个 30 秒窗口)以容忍客户端时钟漂移,但不能无限放宽;
  3. 防重放:同一个 6 位码在有效期内只能成功一次,需要记录已用过的计数器值,否则码被截获后仍可复用;
  4. 限速:6 位码只有一百万种组合,必须限制连续失败次数并触发锁定或冷却,否则可被在线爆破;
  5. 恢复码:为丢失设备的用户提供一次性恢复码,哈希存储且用后作废,并提供解绑与重新绑定路径。

常见误区

  • 用短信当第二因素:短信可被劫持或补卡,安全性显著低于 TOTP;
  • 把密钥放进二维码就不管了:二维码只是传输载体,密钥本身仍需加密存储;
  • 认为“有 2FA 就安全”:若登录页可被实时钓鱼转发,TOTP 同样会被利用,高价值场景应升级为 WebAuthn;
  • 只在前端校验:校验必须完全在服务端完成,前端只是输入与展示。

与其它第二因素的取舍

按抗钓鱼能力排序大致是:WebAuthn(硬件密钥 / 平台验证器)优于 TOTP,TOTP 优于推送确认,短信最弱。选择时同时考虑用户设备的普及度与客服成本。

客户端时间偏差怎么处理

  • 接受相邻窗口:允许前后各一个 30 秒窗口,可覆盖多数设备的时间漂移,同时把可用窗口控制在 90 秒内;
  • 漂移告警:若大量用户集中在同一侧窗口命中,说明客户端普遍偏快或偏慢,应检查服务端时间同步;
  • 同步时间源:服务端必须启用 NTP,时钟漂移会让整个校验体系失效;
  • 恢复码兜底:时钟严重异常时,一次性恢复码是唯一可靠的逃生通道。

上线检查清单

  • 密钥加密存储且不可明文读出;
  • 校验前后各一个时间片,服务端已启用 NTP;
  • 同一验证码只能成功一次(防重放);
  • 连续失败有锁定或冷却,并提供恢复码与解绑入口。