正在加载,请稍候…

OTP 最佳实践:从短信验证码到应用内认证

了解一次性密码(OTP)的工作原理、短信 OTP 的安全风险,以及应用内 OTP 如何提升安全性。包含代码示例和对比表格。

一次性密码(OTP)是多因素认证(MFA)的基石。它在密码之外提供第二层验证,通常通过短信发送或由认证器应用生成。但并非所有 OTP 都同样安全。短信 OTP 曾被认为是安全的,但现在容易受到 SIM 卡劫持、SS7 拦截和钓鱼攻击。应用内 OTP——在您登录的同一应用内生成并显示——提供了更安全、更友好的替代方案。

手持手机显示 OTP 通知的人

什么是 OTP 以及它是如何生成的?

OTP 是一个临时的数字或字母数字代码,仅对单个登录会话或交易有效。它通过种子密钥(服务器和用户设备共享)结合以下方式生成:

  • 基于时间(TOTP):当前时间(通常以 30 秒为间隔)与种子进行哈希运算生成代码。服务器和设备需要大致同步时钟。
  • 基于计数器(HOTP):使用递增计数器代替时间。每次成功登录后,双方计数器递增。

大多数现代应用使用 TOTP,因为它不需要状态同步。该算法定义在 RFC 6238(TOTP)和 RFC 4226(HOTP)中。

工作示例:Python 中的 TOTP 生成

import hmac
import hashlib
import struct
import time

# 共享密钥(base32 编码,如 Google Authenticator 中所示)
secret = "JBSWY3DPEHPK3PXP"  # 示例密钥

# 解码密钥
key = base64.b32decode(secret, casefold=True)

# 获取当前时间步(30 秒)
timestep = int(time.time()) // 30

# 将时间步打包为 8 字节(大端序)
timestep_bytes = struct.pack(">Q", timestep)

# 计算 HMAC-SHA1
hash = hmac.new(key, timestep_bytes, hashlib.sha1).digest()

# 动态截断:取哈希最后 4 位作为偏移量
offset = hash[-1] & 0x0F

# 从偏移量处提取 4 字节
binary_code = struct.unpack(">I", hash[offset:offset+4])[0] & 0x7FFFFFFF

# 生成 6 位代码
otp = binary_code % 10**6
print(f"您的 OTP 是:{otp:06d}")

这正是 Google Authenticator 和 Authy 等应用的工作方式。服务器存储相同的密钥并执行相同的计算来验证代码。

短信 OTP 与应用内 OTP:安全对比

特性 短信 OTP 应用内 OTP
传输信道 蜂窝网络(未加密 SS7) 加密推送通知或应用内生成
抗钓鱼能力 低——代码可被拦截或转发 高——绑定设备和应用会话
SIM 卡劫持防护 强——需要持有设备
用户体验 切换应用,等待短信 一键确认,无需切换应用
成本 按条付费(尤其是国际) 初始开发后免费
监管趋势 正在淘汰(例如菲律宾 BSP 1213 号令) 成为高风险交易的标准

为什么短信 OTP 正在被淘汰

攻击者对短信 OTP 主要有三种攻击方式:

  • SIM 卡劫持:通过欺诈手段将受害者的手机号码转移到攻击者的 SIM 卡上。
  • SS7 拦截:利用电信信令协议漏洞拦截短信。
  • 钓鱼:诱骗用户在虚假网站上输入 OTP。

全球监管机构正在关注。菲律宾 BSP 1213 号令要求所有银行和电子钱包在 2026 年 6 月 30 日前停止将短信 OTP 用于高风险交易。其他东南亚国家预计也将采取类似措施。

应用内 OTP:工作原理及优势

应用内 OTP 是指代码在您正在使用的应用(例如银行应用)内生成或显示。有两种常见实现方式:

  1. 基于推送:服务器向注册设备发送推送通知。用户点击“批准”即可完成认证。不显示代码。
  2. 应用内 TOTP:应用使用存储的密钥生成 TOTP 代码,类似于认证器应用,但嵌入在同一应用中。

两种方法都将蜂窝网络排除在信任链之外。代码永远不会离开设备,用户无需切换应用。

实施注意事项

  • 设备绑定:密钥必须绑定到特定设备,通常使用硬件支持的存储(Android Keystore、iOS Secure Enclave)。
  • 推送通知权限:用户必须为应用启用通知。否则,基于推送的 OTP 将无法工作。
  • 备用机制:提供备用方法(例如恢复代码),以防设备丢失。

常见陷阱

  • 对高风险操作使用短信 OTP:资金转账、密码更改或添加新收款人等交易绝不应仅依赖短信。
  • 以明文存储密钥:服务器必须加密存储共享密钥。如果数据库被攻破,所有 OTP 都将泄露。
  • 忽略时钟漂移:TOTP 需要同步时钟。允许一个小的窗口(例如 ±1 个时间步)来容纳漂移。
  • 不限制 OTP 尝试次数:攻击者可以暴力破解 6 位代码(每次尝试概率为 1/1,000,000)。实施速率限制或 3-5 次失败后锁定。
  • 通过未加密信道发送 OTP:始终对任何 OTP 传递或验证端点使用 HTTPS。

常见问题解答

TOTP 和 HOTP 有什么区别?

TOTP 基于时间(代码每 30 秒更改一次),而 HOTP 基于计数器(代码仅在成功使用后更改)。TOTP 更常见,因为它不需要服务器跟踪计数器。

应用内 OTP 会被钓鱼吗?

难度大得多。由于代码在合法应用内生成,钓鱼网站很难获取它。但是,如果攻击者诱骗用户安装模仿真实应用的恶意应用,他们可能会拦截代码。设备完整性检查有助于缓解这种情况。

短信 OTP 完全没用了吗?

并非完全没用。它仍可用于低风险操作,例如在注册时验证手机号码。但对于身份验证或交易授权,应予以替换。

如何从短信 OTP 迁移到应用内 OTP?

  1. 在您的应用中实现 TOTP 生成器(或使用推送通知)。
  2. 对于现有用户,在下次登录时提示他们启用应用内 OTP。
  3. 提供短信 OTP 仍然有效的宽限期,然后逐步淘汰。
  4. 为丢失设备提供恢复代码。

OTP 的未来是什么?

生物识别(指纹、面部识别)和行为认证(打字模式、设备移动)正在成为更强的替代方案。OTP 最终可能会被完全取代,但目前,应用内 OTP 是比短信 OTP 的重大改进。

使用我们的 OTP 生成器 工具亲自生成一个 TOTP 代码。