一次性密码(OTP),特别是基于时间的一次性密码(TOTP),是双因素认证(2FA)的基石。它们在密码之外增加了第二层安全。然而,跨设备管理 TOTP 密钥、安全备份以及在验证器之间迁移可能比较棘手。本文深入探讨实用的 OTP 管理:生成、安全存储、备份策略以及常见陷阱。

TOTP 的工作原理
TOTP 定义于 RFC 6238。它使用一个共享的密钥(Base32 编码)和当前时间(通常以 30 秒为间隔)生成 6-8 位数字的验证码。算法如下:
- 密钥:一个随机的 Base32 字符串(例如
JBSWY3DPEHPK3PXP)。 - 时间步长:当前 Unix 时间除以 30(或其他周期)。
- HMAC-SHA1:计算 HMAC-SHA1(secret, time_step)。
- 截断:从 HMAC 结果中提取 4 个字节,对 10^6 取模得到 6 位数字。
服务器和验证器应用计算相同的验证码。服务器在一个窗口内(通常 ±1 个时间步长)验证验证码,以容忍时钟偏差。
生成 TOTP 验证码
要生成 TOTP 验证码,你需要密钥。可以通过两种方式获取:
- 扫描二维码:二维码编码了
otpauth://URI。例如:otpauth://totp/Example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30 - 手动输入:将 Base32 密钥输入到你的验证器应用中。
大多数验证器应用(如 Google Authenticator、Microsoft Authenticator、Authy 或开源应用如 Aegis)都支持这两种方式。
密钥的安全存储
你的 TOTP 密钥与密码一样敏感。如果攻击者获取了它们,就可以无限期地生成有效的 2FA 验证码。因此:
- 静态加密:将密钥存储在加密数据库中(例如 SQLCipher)。
- 使用平台密钥存储:在 Android 上使用 Android Keystore;在 iOS 上使用 Keychain。
- 启用应用锁:需要指纹、面部解锁或 PIN 才能打开验证器应用。
- 禁用截屏:在 Android 上设置
FLAG_SECURE以防止屏幕捕获。
备份策略
丢失手机意味着丢失对所有 2FA 账户的访问权限,除非你有备份。以下是常见的备份方法:
| 方法 | 优点 | 缺点 |
|---|---|---|
| 加密导出 | 完全控制,可移植 | 必须安全管理备份文件 |
| 云同步(例如 GitHub Gist) | 自动,跨设备 | 需要信任云提供商;需要端到端加密 |
| 打印二维码 | 离线,无数字风险 | 物理丢失或损坏;需要重新扫描每个 |
| 多设备设置 | 冗余 | 必须确保所有设备安全 |
示例:使用 GitHub Gist 进行加密备份
某些验证器应用(如 OTP Box)允许同步到私有 GitHub Gist。备份在上传前在客户端加密:
- 加密:使用 PBKDF2-HMAC-SHA256(600,000 次迭代)从备份密码派生加密密钥。使用 AES-256-GCM 加密 JSON 导出文件。
- 上传:将密文推送到私有 Gist。
- 恢复:下载 Gist,使用相同密码解密,然后导入应用。
这确保即使 GitHub 被攻破,也只有你能读取密钥。
在验证器之间迁移
当更换手机或验证器应用时,你需要传输 TOTP 密钥。以下是安全的工作流程:
- 从旧应用导出:使用应用的导出功能(通常是加密的 JSON 或
otpauth://URI)。 - 安全传输:使用本地数据线、加密消息或在可信设备上显示的临时二维码。避免使用未加密的云存储。
- 导入新应用:扫描二维码或导入文件。
- 验证:在新应用上测试一个验证码,然后再禁用旧应用。
⚠️ 安全提示:切勿通过未加密的渠道(电子邮件、短信、公共云)共享你的密钥或导出文件。将它们视为密码。
常见陷阱
- 时钟偏差:如果设备时间不准,TOTP 验证码可能失败。启用自动时间同步。
- 忘记备份密码:如果加密了备份但忘记了密码,密钥将无法恢复。
- 使用短信 OTP:短信容易受到 SIM 卡交换和拦截攻击。优先使用 TOTP 或硬件令牌。
- 未测试恢复:始终在辅助设备上测试备份恢复。
- 共享二维码:将二维码视为密钥;它们包含原始密钥。
完整示例:端到端 TOTP 设置与备份
让我们使用一个假设的验证器应用(类似于 Aegis 或 OTP Box)逐步完成一个完整场景。
步骤 1:添加账户
从服务(例如 Google、GitHub)扫描二维码。应用将密钥存储在加密数据库中。
步骤 2:创建加密备份
- 进入设置 > 备份。
- 选择“导出到文件”并设置一个强备份密码(例如
P@ssw0rd!2024)。 - 应用导出一个使用 AES-256-GCM 加密的 JSON 文件。将其保存到安全位置(例如加密的 USB 驱动器)。
步骤 3:通过 GitHub Gist 同步(可选)
- 生成一个具有
gist权限的 GitHub 个人访问令牌。 - 在应用中输入令牌并设置相同的备份密码。
- 点击“推送到 Gist”。应用在客户端加密数据并上传。
- 在另一台设备上,输入令牌和密码,然后“从 Gist 拉取”。
步骤 4:在新手机上恢复
- 安装相同的验证器应用。
- 选择“从文件导入”并选择加密的备份文件。
- 输入备份密码。应用解密并导入所有账户。
- 从一个账户验证一个验证码以确认成功。
常见问题
如果我丢了手机且没有备份怎么办?
你将失去对所有 2FA 账户的访问权限。大多数服务在初始设置期间提供备份码;使用这些备份码重新获得访问权限,然后使用新的验证器重新注册。
将 TOTP 密钥存储在云端安全吗?
仅当在上传前进行端到端加密时才安全。像 Authy 这样的服务在同步时会加密,但你必须信任它们的实现。具有客户端加密的开源应用(例如使用 GitHub Gist 的 OTP Box)能给你更多控制。
我可以在多个设备上使用同一个密钥吗?
可以。密钥只是一个密码;多个验证器可以生成相同的验证码。但是,每个设备的时间必须正确。这对于冗余很有用。
我应该多久备份一次?
添加任何新的 2FA 账户后,创建一个新的备份。如果使用云同步,它可以自动进行。
TOTP 和 HOTP 有什么区别?
TOTP 使用时间作为计数器;HOTP 使用事件计数器。TOTP 更常见,因为验证码会自动刷新。HOTP 每次使用后需要手动同步。
尝试使用我们的 OTP 生成器 生成和管理 TOTP 验证码。它是一个方便的工具,用于测试或无需应用即可快速生成验证码。
记住:你的 2FA 密钥是你数字王国的钥匙。安全备份它们,切勿共享。