# OTP 的送达与风险：验证码到底证明了什么

一次性密码证明的是：在输入的那一刻，这个号码在用户手里。它不证明身份，送达回执也不证明有人读过。送达、拦截、号码回收和表单本身，共同决定这道验证站不站得住。

- OTP 证明的是当时对号码的控制，不是身份。

- 送达回执只说明网络状态，不说明有人读过验证码。

- 号码回收、SIM 卡补换、呼转和钓鱼是验证码泄露的主要途径。

- 限流、发送方注册和号码检查能减少滥用，但都不能证明身份。

## OTP 证明什么

OTP 只回答一个问题：此刻坐在您面前的人，能不能在这个号码上收到短信？用于找回账号和登录，这个答案有用，因为它把会话绑在用户能控制的东西上。它不是身份证件。号码可能被回收、被换到新 SIM 卡、被呼转，也可能被同住的另一个人看到。
设计时要分清这一点。低价值操作，一个 OTP 就够了。涉及转账、改密码或新增收款人，就要再加一道检查：延迟一段时间、在已有会话里二次确认、回拨已知渠道，或者人工复核。验证码只是一个因素，不是整个决定。

### 短信路径，以及验证码可能泄露的地方

送验证码的那条链路，也是验证码可能被看到、被延迟、被送到错误手机的地方。

Alt: 从应用到手机再到回执的七步短信路径，标出多个验证码可能泄露的位置。

应用把验证码交给网关，短信中心查询用户位置，服务该用户的交换中心把短信送到手机。回执沿同一条链路返回。验证码可能在应用、手机、号码本身或收件人那里泄露。网络路径解释的是送达，解释不了把验证码转发出去的人。

| Item | Value | Note |
| --- | --- | --- |
| 状态一 · 1 | 应用 |  |
| 状态一 · 2 | SMPP 网关 |  |
| 状态一 · 3 | SMSC |  |
| 状态一 · 4 | HLR / HSS |  |
| 状态一 · 5 | MSC / MME |  |
| 状态一 · 6 | 手机 |  |
| 状态一 · 7 | 送达回执 |  |

Source: 3GPP TS 23.040：短信架构 (https://www.3gpp.org/ftp/Specs/archive/23_series/23.040/)

## 验证码从哪里漏出去

SIM 卡补换会把号码换到一张新卡上。攻击者让营业厅或客服相信自己是机主，下一条验证码就进了新卡。号码回收不需要攻击者也能造成同样的结果。运营商把一个停用号码重新放号，新机主收到的是给旧账号的验证码。两种情况都说明，要查号码最近有没有携转或重新分配。
呼转和语音信箱转文字会把短信送到另一个收件箱。钓鱼直接复制表单，把验证码收走，网络根本看不到攻击。网络路径上的拦截更少见，也不在应用的控制范围内。实际应对是加第二个因素，而不是把验证码做长。定义见 [OTP 词条](/zh/resources/glossary/otp/)。

## 有用的控制

同一个号码、同一个 IP 和同一台设备请求验证码，都要限制频率。有效期要短，一个验证码只能用一次，并把它绑定到发起请求的会话。发送方要注册，内容要克制。看起来像营销的验证码可能被过滤，被过滤的验证码只会变成客服工单，不会变成登录。
信任号码之前先检查它。收不到短信的号码、刚携转的号码、频繁重置的号码，都值得多一道步骤。高价值操作要求已有会话或第二个渠道。把请求、提交、回执和输入验证码记成独立事件，才能分清是送达问题还是用户问题。
验证码本身也要认真设计。用密码学随机源生成，存哈希，几分钟内过期，只允许成功使用一次，并限制每个验证码和每个会话的尝试次数。不要暴露号码是否存在。先建账号记录再发短信，避免重试造出一个永远完不成的账号。

### 五个指标，附定义

| 指标 | 定义 | 它说明什么 |
| --- | --- | --- |
| 送达率 | 已送达回执数除以已提交数 | 网络是否接受了短信，不说明有没有人读 |
| 完成率 | 已输入验证码数除以已送达数 | 短信和表单对用户是否好使 |
| 送达时长 | 从提交到回执的中位数和 95 分位 | 路由是否慢，用户要等多久才重发 |
| 重发率 | 重发数除以已送达数 | 用户是不是等太久、输错，或者根本没看到第一条 |
| 拦截率 | 被风险规则拒绝的请求数除以尝试数 | 规则是太严、太松，还是流量本身有问题 |

按市场、发送方和路由分别看。一个全局平均会把出问题的那条路由盖住。

## 量流程，不要只量发送

返回 message ID 不等于验证码送达，验证码送达也不等于登录完成。用您能控制的事件搭漏斗：提交、回执、输入验证码、成功。再和服务商的视角对一遍。您的送达率和服务商的对不上，可能是回执没到您的处理程序，而不是短信没到手机。
指标一动，就回看流程。送达率稳定、完成率下降，问题在表单、验证码有效期或发送方。提交量稳定、送达率下降，问题在路由、号码或内容过滤。重发率上升，问题在送达时长。修数据指到的那一步，不要修最容易改的那一步。
给整条流程定一个复核日期。号码会换手，路由会变，模板会过时。上线时好用的流程，半年后可能悄无声息地失效，代码没变，服务商也没变。

### Check what you learned

**用户把验证码转发给朋友。这个验证码还能证明身份吗？**

不能。它只证明那个号码当时能收到验证码。拿到验证码的人都能用。

**回执显示已送达，但用户始终没看到验证码。查什么？**

查手机状态、短信应用和垃圾箱、发送方和路由。已送达是网络状态，不是手机屏幕。

**为什么完成率比送达率更有用？**

送达止于网络。完成率把用户、验证码有效期和表单都算进来，多数失败正出在这里。

## FAQ

**OTP 等于双因素认证吗？**

OTP 可以作为第二个因素。单独用时，它只是一个因素：当时持有这个号码。

**验证码越长越安全吗？**

长度能防猜，但挡不住 SIM 卡补换、呼转或钓鱼。高价值操作要加第二道检查。

**送达回执能证明用户读了吗？**

不能。它报告的是网络状态，比如已送达、已过期或未送达，和读没读、输没输无关。

**应该自动重发吗？**

按用户动作重发，不要按计时器重发。自动重发会放大成本，还可能掩盖路由问题。

**应该记录什么？**

请求、提交和 message ID、回执和状态、验证码输入结果。都作为独立事件带时间戳保存。

**回执显示已送达，但用户什么也没收到。换服务商之前应该查什么？**

先查自己这一侧，因为送达回执只说明网络接收了短信，不说明手机上显示了什么。用[短信内容预检](/zh/tools/content-precheck/)检查模板，用[短信分段计数器](/zh/tools/sms-segments/)计算分段数，再用 [SMPP 与 DLR 错误码解码](/zh/tools/smpp-decoder/)读懂提交和回执的状态码。如果这些都没问题，在迁移流量之前，先用自己的手机测试出问题的目的地，一次一个目的地。

## Sources

- [3GPP TS 23.040：短消息业务的技术实现](https://www.3gpp.org/ftp/Specs/archive/23_series/23.040/) — Accessed: 2026-10-19
- [3GPP TS 23.003：编号、寻址与标识](https://www.3gpp.org/ftp/Specs/archive/23_series/23.003/) — Accessed: 2026-10-19
- [smpp.org：送达回执与消息状态](https://smpp.org/smpp-delivery-receipt.html) — Accessed: 2026-10-19

Updated: 2026-11-03