前言

账号密码一旦泄露,攻击者就可能直接登录账户。密码泄露的渠道并不少见:钓鱼网站、撞库攻击、恶意浏览器扩展、公共设备登录,甚至是不同站点复用同一密码。

双因素认证(Two-Factor Authentication,2FA)在密码之外增加了一道独立验证。即使攻击者拿到了密码,只要没有第二因素,通常仍无法完成登录。

Google Authenticator 是最常见的 2FA 工具之一。它不依赖短信网络,能够离线生成短时有效的动态验证码,因此被大量网站、代码托管平台、云服务和交易平台使用。

什么是双因素认证

身份验证因素通常可以分为三类:

因素 含义 示例
你知道的东西 知识或秘密 密码、PIN 码、安全问题
你拥有的东西 实体设备或凭证 手机、硬件安全密钥、Authenticator 应用
你本身的特征 生物特征 指纹、人脸、虹膜

2FA 要求至少使用两种不同类型的因素。例如:

1
2
3
密码 + Google Authenticator 动态验证码
密码 + 短信验证码
密码 + 硬件安全密钥

注意,两个密码问题,或者密码加另一个静态密码,都不算真正的双因素认证,因为它们都属于“你知道的东西”。

常见 2FA 方案对比

不同方案的安全性、使用成本和恢复难度并不相同。

方案 优点 风险或限制 推荐程度
短信验证码 使用门槛低,用户熟悉 可能受 SIM 换卡、短信拦截和信号影响 可作为过渡或恢复手段
邮箱验证码 无需安装应用 邮箱本身成为单点风险 一般
TOTP 动态验证码 离线可用,标准成熟,兼容广 需要保管密钥和恢复码 推荐
推送确认 操作方便,可附带设备信息 依赖网络和厂商服务 推荐
FIDO2/WebAuthn 硬件密钥或通行密钥 抗钓鱼能力强,安全性高 兼容性和备份策略需要规划 高价值账号强烈推荐

Google Authenticator 所使用的主要是 TOTP(Time-based One-Time Password,基于时间的一次性密码)。它比短信验证码更不容易受到运营商链路攻击,但它不能自动识别钓鱼网站,因此登录时仍需要认真核对域名。

TOTP 动态验证码的工作原理

启用 TOTP 时,网站会生成一段随机密钥,并以二维码或手动输入密钥的形式展示给用户。Authenticator 应用扫描二维码后保存同一段密钥。

之后,网站和手机分别根据“共享密钥 + 当前时间”计算验证码。两边计算结果相同,就可以完成校验。

flowchart LR
    A[网站生成随机 TOTP 密钥] --> B[展示二维码或手动密钥]
    B --> C[Authenticator 扫码并保存密钥]
    A --> D[服务端保存密钥的受保护版本]
    C --> E[共享密钥 + 当前时间片]
    D --> F[共享密钥 + 当前时间片]
    E --> G[手机生成 6 位动态验证码]
    F --> H[服务端计算期望验证码]
    G --> I[用户输入验证码]
    I --> J{验证码是否匹配}
    H --> J
    J -- 是 --> K[认证通过]
    J -- 否 --> L[认证失败]

常见的 TOTP 配置是:每 30 秒刷新一次、6 位数字、HMAC-SHA-1。SHA-1 在这里是 TOTP 标准中用作 HMAC 的兼容选项,不等同于将 SHA-1 用于密码存储。新系统也可以使用 SHA-256 或 SHA-512,但必须确认客户端兼容。

简化后的计算过程可以表示为:

1
2
3
时间步长 = floor(当前 Unix 时间 / 30)
HMAC = HMAC(共享密钥, 时间步长)
验证码 = 对 HMAC 结果做动态截断后取模 10^6

验证码会随时间变化,旧验证码很快失效。为了容忍手机和服务器之间的轻微时间偏差,服务端通常会额外验证相邻的一个时间窗口;窗口不能设置过大,否则会扩大可被猜中的时间范围。

使用 Google Authenticator 配置 2FA

不同网站的界面略有区别,但配置流程基本一致。

1. 安装认证器应用

在手机的官方应用商店安装 Google Authenticator。也可以选择支持标准 TOTP 的其他认证器;关键是确认来源可靠,并了解它的加密、同步和迁移能力。

不要从搜索结果中的不明下载站安装,也不要把动态验证码截图、二维码或手动密钥发送给他人。

2. 在网站安全设置中启用 2FA

通常入口位于:

1
账户设置 -> 安全设置 -> 双因素认证 / 两步验证

选择“认证器应用”后,网站会展示二维码。二维码本质上包含一个 otpauth:// 配置链接,其中最重要的是 TOTP 密钥。

3. 扫描二维码并完成验证

在 Google Authenticator 中新增账号,扫描网页上的二维码。应用会立即开始显示 6 位或 8 位验证码。

把当前验证码输入网站的确认框。验证成功后,网站会正式启用 2FA。

sequenceDiagram
    participant U as 用户
    participant W as 网站
    participant A as Google Authenticator

    U->>W: 进入 2FA 设置并选择认证器应用
    W->>W: 生成 TOTP 密钥
    W-->>U: 展示二维码和备用手动密钥
    U->>A: 扫描二维码
    A->>A: 保存密钥并生成动态验证码
    U->>W: 提交当前验证码
    W->>W: 校验 TOTP
    W-->>U: 启用成功,显示恢复码

4. 保存恢复码

恢复码是设备丢失、手机损坏或认证器数据不可用时的重要后备手段。每个恢复码一般只能使用一次。

建议:

  • 使用密码管理器的安全笔记保存恢复码。
  • 或将恢复码离线保存到受保护的位置。
  • 不要只保存在正在用于生成验证码的同一台手机里。
  • 不要把恢复码、二维码和密码放到公开网盘或聊天记录中。

登录时发生了什么

启用 2FA 后,常规登录由“密码校验”变成“密码校验 + 第二因素校验”。

flowchart TD
    A[输入账号和密码] --> B{密码是否正确}
    B -- 否 --> X1[拒绝登录并执行限速]
    B -- 是 --> C{账户是否启用 2FA}
    C -- 否 --> D[创建登录会话]
    C -- 是 --> E[要求输入 TOTP 验证码]
    E --> F{验证码或恢复码有效吗}
    F -- 否 --> X2[拒绝登录并记录风险事件]
    F -- 是 --> G[创建登录会话]
    D --> H[进入账户]
    G --> H

这里的核心价值是:密码和认证器密钥通常不在同一个系统中泄露。攻击者即便通过钓鱼或撞库获得了密码,也还需要拿到用户手机上的验证码才能登录。

更换手机、迁移和恢复

2FA 最容易被忽视的是可恢复性。只在旧手机上保存认证器账号,等到换机或手机遗失再处理,往往会让自己无法登录重要服务。

更换手机前

最稳妥的做法是,在旧手机仍可用时逐个迁移高价值账号:

  1. 先确认每个网站的恢复码仍可用。
  2. 在新手机安装认证器应用。
  3. 根据认证器应用提供的迁移功能,或在网站中重新绑定新设备。
  4. 使用新手机验证码完成一次登录测试。
  5. 确认成功后,再从旧设备移除账号或抹除设备数据。

Google Authenticator 支持账号迁移,但迁移二维码也等同于可生成验证码的凭证。迁移时应避免被他人拍摄,不要在公开屏幕共享中展示二维码。

手机遗失后

优先级建议如下:

1
2
3
4
5
1. 使用恢复码登录
2. 使用已登录的可信设备更新 2FA
3. 使用网站提供的身份核验恢复流程
4. 立即修改密码,并撤销丢失设备的会话
5. 检查近期登录记录、绑定邮箱和支付方式

不要为了“方便恢复”而长期关闭 2FA。正确做法是提前准备恢复码、备用硬件密钥或第二个受控认证设备。

使用 2FA 的安全建议

为重要账号优先启用

应优先保护能够影响其他账号的入口:

  • 主邮箱和 Apple ID、Google 账号等身份账号。
  • 密码管理器。
  • GitHub、GitLab、云服务器和域名注册商。
  • 支付、交易和数字资产相关平台。
  • 社交媒体和即时通信账号。

主邮箱尤其重要,因为许多网站的密码重置链接都会发送到邮箱。邮箱失守,其他账户的安全边界也会随之变弱。

不要分享验证码和二维码

任何索要验证码的人,都可能借此完成登录。客服、同事和平台官方通常不会要求用户提供当前的 TOTP 验证码、恢复码或二维码。

二维码不是普通图片,而是认证密钥的载体。泄露二维码后,应立即在网站中重置该账号的 2FA 密钥,而不是只修改密码。

警惕实时钓鱼

TOTP 能防住单纯的密码泄露,但钓鱼网站可以实时转发用户输入的密码和验证码。用户输入验证码后,攻击者可能在验证码失效前立刻向真实网站登录。

因此还应做到:

  • 从书签或官方应用进入服务,不随意点击登录链接。
  • 登录前检查域名和浏览器地址栏。
  • 不在陌生页面输入恢复码。
  • 高价值账号优先启用 WebAuthn、通行密钥或硬件安全密钥。

FIDO2/WebAuthn 会把验证与真实域名绑定,能更有效地抵御仿冒站点,是 TOTP 的重要升级方向。

开发者接入 TOTP 的实践要点

如果为自己的系统增加 2FA,不应只在登录页加一个验证码输入框,还需要完成密钥保护、恢复、会话管理和风险控制。

推荐的启用流程

sequenceDiagram
    participant U as 用户
    participant B as 浏览器
    participant S as 应用服务
    participant D as 数据库

    U->>B: 请求启用 2FA
    B->>S: 创建待确认的 TOTP 配置
    S->>S: 使用加密安全随机数生成密钥
    S->>D: 临时保存加密后的待确认密钥
    S-->>B: 返回 otpauth URI / 二维码
    U->>B: 输入认证器验证码
    B->>S: 确认验证码
    S->>S: 校验当前及相邻时间窗口
    S->>D: 将配置标记为已启用,并生成恢复码
    S-->>B: 返回一次性展示的恢复码

实现时建议遵循以下原则:

项目 建议
TOTP 密钥生成 使用密码学安全随机数,不要使用可预测的随机函数
密钥存储 加密后存储,密钥加密密钥放在 KMS、密钥管理服务或受保护环境变量中
激活方式 用户输入正确验证码后才正式启用,避免未扫描二维码导致锁定
验证窗口 一般校验当前窗口和前后各一个窗口,并监控时钟偏差
重放控制 对已成功使用的时间步做短期记录,关键场景避免同一验证码重复提交
恢复码 只展示一次;服务端应只存储其哈希值
限速 对登录、验证码验证和恢复码尝试执行限速与告警
会话控制 修改密码、禁用 2FA 或更换认证器后,可撤销其他会话

不要把 TOTP 密钥当作普通字段

TOTP 密钥可以持续生成验证码,因此其敏感级别接近密码。它不应该出现在应用日志、分析事件、错误堆栈、客服工单或前端持久化缓存中。

服务端日志可以记录“用户已通过 2FA”或“验证码校验失败”,但不要记录原始密钥、otpauth 链接、二维码内容和用户提交的验证码。

常见误区

误区一:开启 2FA 后可以复用弱密码

2FA 是额外防线,不是弱密码的替代品。仍应为每个网站使用独立的长随机密码,最好交由密码管理器生成和保存。

误区二:短信验证码和 TOTP 完全一样安全

两者都是第二因素,但攻击面不同。短信受运营商和手机号控制链路影响更大;TOTP 不依赖手机信号,但需要保护认证器密钥。高价值账户还应考虑硬件安全密钥或通行密钥。

误区三:恢复码保存到手机相册就够了

同一台手机丢失时,相册中的恢复码也可能一起失去。恢复材料需要与日常认证设备分离保存。

误区四:Authenticator 没有网络就不能用

TOTP 依赖本地时间和已保存的密钥,通常不需要网络。手机时间明显不正确时,验证码才可能校验失败。

总结

双因素认证把账户安全从“只要密码泄露就可能失守”提升为“两种独立凭证都要被攻破”。对于个人用户,Google Authenticator 等 TOTP 认证器是低成本、兼容性强的选择。

可以把日常实践归纳为:

1
2
3
4
5
6
为重要账号启用 2FA
使用独立的强密码
妥善保存恢复码
更换手机前完成迁移和测试
不泄露验证码、恢复码和二维码
高价值账号优先使用通行密钥或硬件安全密钥

安全不是一次设置就结束的功能。定期检查账号的登录记录、恢复方式、可信设备和 2FA 绑定状态,才能让这道防线在真正需要时发挥作用。