# 认识 2FA 与 OTP：从短信验证码到动态令牌的技术演进

> 从双因素认证 2FA 切入，梳理 OTP 在身份认证中的位置、短信验证码的局限、HOTP 与 TOTP 的算法演进，以及不同验证方案在安全性、体验和成本上的取舍。

- 发布于：2026-01-01
- 更新于：2026-01-01
- 分类：学习
- 标签：后端
- 原文：https://chanx.tech/blog/otp

## 一、为什么需要 2FA

账号登录最常见的方式是用户名加密码。但密码有一个天然问题：它是静态凭证。

只要密码泄露，攻击者就可以在之后反复尝试使用它。撞库、钓鱼、弱密码、密码复用，本质上都在利用这个问题。

2FA 是 Two-Factor Authentication，双因素认证。它的核心思路是：不要只依赖一种凭证，而是让用户同时证明两个不同维度的身份因素。

常见认证因素通常分成三类：

- 你知道什么：密码、PIN 码、安全问题
- 你拥有什么：手机、认证器、硬件令牌
- 你是谁：指纹、人脸等生物特征

如果登录时只输入密码，通常只能证明“你知道什么”。如果在密码之外，再要求输入短信验证码、TOTP 动态码，或确认一次设备推送，就增加了“你拥有什么”这一层。

OTP 和 2FA 的关系可以这样理解：

```txt
2FA 是认证方案
OTP 是常用的第二因素实现方式之一
```

也就是说，OTP 可以用于 2FA，但 2FA 不等于 OTP。2FA 也可以通过硬件安全密钥、生物识别、设备确认等方式实现。

## 二、什么是 OTP

OTP 是 One-Time Password，一次性密码。它指的是一种只在单次认证中有效的动态密码。

和传统静态密码相比，OTP 有几个明显特征：

- 一次性：每个密码只用于一次认证，使用后立即失效
- 时效性：密码通常只有几十秒到几分钟的有效期
- 动态生成：密码根据预设规则生成，不需要用户长期记忆

OTP 的价值，是把密码的可用窗口压缩到很短，并让每次认证使用不同的凭证。

从实现方式看，OTP 并不是单一技术。它可以由服务器随机生成后下发，也可以由客户端和服务端基于共享密钥独立计算。

常见形态包括：

- 短信验证码
- 邮件验证码
- HOTP 动态令牌
- TOTP 动态令牌
- 硬件 OTP 令牌

此外，推送式确认、Passkey、生物识别等也经常和 OTP 一起出现在多因素认证体系中。它们不一定属于严格意义上的 OTP，但解决的是相邻的身份确认问题。

不同验证方式在安全性、体验和成本上的差异很大。

## 三、短信验证码：最熟悉的 OTP

用户在登录页输入手机号，点击“获取验证码”，随后收到一条 6 位数字短信。这就是最常见的 OTP 形态。

短信验证码通常满足两个条件：

- 只能使用一次
- 在有限时间内有效

它的实现模式很直接：

```txt
用户请求验证码
  -> 服务端生成随机数字
  -> 服务端保存验证码和过期时间
  -> 通过短信网关下发
  -> 用户输入验证码
  -> 服务端校验是否匹配、是否过期、是否已使用
```

短信 OTP 的优势是门槛低。用户不需要安装额外应用，只要能接收短信，就能完成验证。

但它的安全边界依赖通信链路和手机号控制权，因此也存在一些天然问题：

- 短信可能延迟或丢失
- SIM 卡可能被补卡或劫持
- 手机号不一定等同于用户本人
- 短信内容在传输链路上存在被拦截风险
- 海外或跨运营商场景下成本和稳定性不可控

所以短信验证码更适合作为大众应用的低门槛验证方式，而不是高安全等级场景的唯一认证手段。

## 四、从网络下发到算法生成

短信 OTP 的一个核心问题是：验证码需要通过网络传输。

只要密码需要从服务端下发到用户设备，就会存在通信链路风险。于是另一类方案出现了：客户端和服务端不传输验证码，而是各自独立算出同一个验证码。

需要注意的是，这并不意味着完全没有分发过程。算法生成型 OTP 仍然需要在绑定阶段把共享密钥安全地交给认证器，例如通过二维码或硬件初始化流程完成。它减少的是后续每次认证时验证码在网络中传输的风险。

这类方案依赖三个前提：

- 客户端和服务端共享同一个密钥
- 双方使用同一套算法
- 双方使用一致的动态输入，例如计数器或时间

简化后可以表示为：

```txt
共享密钥 + 动态因子 + HMAC
  -> 一次性密码
```

由于验证码不需要通过短信或邮件下发，这类方案可以降低通信链路带来的风险，也能在离线状态下生成动态验证码。

HOTP 和 TOTP 就是这类算法生成型 OTP 的代表。

## 五、HOTP：基于计数器的一次性密码

HOTP 是 HMAC-Based One-Time Password，基于 HMAC 的一次性密码。它定义在 RFC 4226 中。

HOTP 的动态因子是计数器。

```txt
HOTP = Truncate(HMAC(secret, counter)) mod 10^digits
```

客户端和服务端持有相同的 `secret`，并维护同一个 `counter`。每次生成或验证成功后，计数器向前推进。

这种方案的优点是每次密码都不同，不依赖网络下发。但它也有一个关键问题：计数器同步。

如果客户端计数器向前走了很多步，而服务端没有同步，就可能出现验证失败。实际系统通常会设置一个向前查找窗口，允许服务端在一定范围内寻找匹配计数器，但这也会增加重同步和风控复杂度。

因此 HOTP 更适合硬件令牌、按键触发式令牌等可控场景。

## 六、TOTP：基于时间的一次性密码

TOTP 是 Time-Based One-Time Password，基于时间的一次性密码。它定义在 RFC 6238 中。

TOTP 可以理解为 HOTP 的时间版本。它不再使用计数器，而是把当前时间切成固定窗口。

```txt
TOTP = HOTP(secret, time_step)
time_step = floor(current_unix_time / period)
```

`period` 通常是 30 秒。也就是说，在同一个 30 秒窗口内，客户端和服务端只要拥有同一个密钥，并且时间基本一致，就能计算出相同的验证码。

相比 HOTP，TOTP 不需要维护计数器同步，使用体验更好，因此成为双因素认证中最常见的动态令牌方案。

它的代价是对时间同步有要求。如果用户设备时间和服务端时间偏差过大，就可能导致验证码验证失败。实际系统通常会允许前后各一个时间窗口的容错。

## 七、OTP 家族的其他形态

除了短信、HOTP 和 TOTP，OTP 还有一些常见变体。

### 邮件 OTP

邮件 OTP 和短信 OTP 类似，只是把下发通道从短信换成邮件。

它的成本较低，适合注册确认、邮箱绑定、低风险找回流程。但邮箱本身也可能被盗，因此不适合作为高安全等级操作的唯一验证方式。

### 硬件 OTP

硬件 OTP 把密钥保存在专用设备中，例如硬件 OTP 令牌，或支持 OATH-HOTP/OATH-TOTP 的硬件设备。

这类方案的优势是密钥不容易被普通恶意脚本读取，安全性更高。代价是硬件成本、发放成本和丢失后的恢复成本更高，通常用于金融、企业内控、高权限后台等场景。

### 相邻形态：推送式验证

推送式验证严格来说不一定是 OTP，因为用户不一定会看到或输入一个一次性密码。它更像是一种挑战确认机制：当用户触发登录或敏感操作时，服务端向已绑定设备发送验证请求，用户点击确认即可完成认证。

它的体验更好，也可以结合设备指纹、地理位置、风险评分等能力。但实现成本更高，并且需要处理推送到达率、设备绑定和误点确认等问题。

## 八、前端在 OTP 中的职责

前端实现 OTP 功能时，重点不是“生成密码”，而是把认证流程做清楚。

在短信 OTP 或邮件 OTP 场景中，前端通常负责：

- 触发验证码发送
- 显示倒计时
- 限制重复点击
- 收集用户输入
- 做基础格式校验
- 展示错误和重试状态

在 TOTP 场景中，前端通常负责：

- 展示绑定二维码
- 引导用户使用认证器扫码
- 收集用户输入的动态验证码
- 展示恢复码提示
- 在敏感操作前触发二次验证

一个简单的验证码格式处理可以是：

```ts
function normalizeOtp(input: string) {
  return input.replace(/\s|-/g, '')
}

function isSixDigitOtp(input: string) {
  return /^\d{6}$/.test(normalizeOtp(input))
}
```

需要注意的是，前端只能做体验层面的校验。验证码是否正确、是否过期、是否已使用、是否触发风控，都应该由服务端判断。

## 九、如何选择 OTP 方案

不同 OTP 方案适合不同场景。可以从安全性、用户体验和实施成本三个维度判断。

| 方案 | 安全性 | 用户体验 | 实施成本 | 适用场景 |
| --- | --- | --- | --- | --- |
| 短信 OTP | 中 | 高 | 中 | 大众登录、手机号验证 |
| 邮件 OTP | 低到中 | 中 | 低 | 注册确认、邮箱绑定 |
| TOTP | 高 | 中 | 低到中 | 两步验证、敏感操作 |
| HOTP | 高 | 中 | 中 | 硬件令牌、离线令牌 |
| 硬件 OTP | 很高 | 中到低 | 高 | 金融、企业高权限场景 |
| 推送式验证 | 高 | 高 | 高 | 移动端登录、企业身份认证 |

如果是普通登录注册，短信或邮件 OTP 的覆盖面更好。如果是账户安全增强，TOTP 更适合作为第二因素。如果是高风险资产或高权限操作，硬件令牌或更强的 MFA 方案更稳妥。

## 十、OTP 之外：新的认证方式与风控系统

随着 Passkey、生物识别和设备绑定的发展，OTP 不再是身份认证的唯一方向。

Passkey 使用公钥密码学减少了密码和验证码被钓鱼的风险；生物识别提升了本地解锁体验；设备绑定让认证系统可以更好地识别“是不是常用设备”。

但 OTP 仍然有价值。它简单、成熟、跨平台，能作为多因素认证中的一层防护。

更现实的趋势不是 OTP 消失，而是 OTP 和其他认证方式组合使用：

```txt
密码
  + 设备识别
  + TOTP / 推送确认
  + 风险控制
```

安全系统很少依赖单点能力，真正可靠的是分层防护。

2FA、OTP、TOTP、硬件令牌，本质上都在增强某一次认证动作的可信度。但在真实业务里，账户安全不只发生在“输入验证码”这一刻。

一个账号是否安全，还要看更多上下文：

- 登录设备是否常见
- IP、地区、网络环境是否异常
- 登录时间是否符合用户习惯
- 操作路径是否突然变化
- 是否存在批量撞库、刷接口、自动化脚本行为
- 敏感操作金额、频率、对象是否异常

这些信息无法只靠一个验证码判断，通常需要由风控系统持续分析。

风控系统会结合设备指纹、行为序列、历史画像、业务规则和模型评分，决定当前请求应该放行、拦截，还是触发更强的二次验证。

所以更完整的账户安全链路通常是：

```txt
基础登录
  -> 2FA / OTP
  -> 设备识别
  -> 行为分析
  -> 风险评分
  -> 动态处置
```

OTP 更像是安全体系里的一个重要组件，而不是全部答案。对于普通产品来说，验证码能显著提升攻击成本；对于高风险业务来说，真正起决定作用的往往是验证码背后的风控体系。

## 总结

OTP 的本质，是让每次认证使用一个短生命周期、不可重复使用的动态凭证。

短信验证码是最熟悉的 OTP，但它依赖通信链路；HOTP 和 TOTP 则通过共享密钥和算法同步，让客户端和服务端独立生成验证码。

理解 OTP 的技术演进，有助于在不同业务场景中做出更合适的认证方案选择。下一篇会进一步展开 TOTP 的生成原理、绑定流程、验证流程和前端职责边界。
