一、引言:数字世界的“一次性钥匙”

在今天的数字生活中,我们已经习惯了这样的场景:登录银行账户时,除了输入密码,还要输入一个6位数字的动态验证码;使用支付宝支付时,即使手机没有网络,付款码依然能够正常生成;开启某个网站的二次认证时,扫描一个二维码就能获得30秒刷新一次的数字。

这些看似平常的功能,背后依赖的正是 OTP(One-Time Password,一次性密码) 技术。OTP 是一种每个密码只能使用一次的认证机制,根据专门算法生成不可预测的随机数字组合,每个口令仅对单次登录会话或交易有效。与静态密码不同,OTP 的有效期极短(通常 30 到 60 秒),即使被截获也几乎无法复用,因此被广泛应用于网银登录、第三方支付、证券交易、企业信息系统等安全敏感场景。

OTP 的核心原理其实很简单:客户端和服务端各自持有一个共享密钥(种子) ,再结合一个不断变化的动态因子(如时间或计数器),通过相同的算法计算出同一串数字,然后进行比对验证。动态因子的不同选择,衍生出了 OTP 家族中几种截然不同的算法——HOTPTOTP 和 OCRA

本文将系统地介绍 OTP 家族的发展脉络,从 HOTP 的原理到 TOTP 的普及,再到 OCRA 在交易签名领域的应用,最后探讨国密算法与 OTP 的结合实践,为你呈现一个完整的 OTP 知识图谱。

二、OTP 的核心原理:一个公式,两种因子

在深入了解各算法之前,有必要先理解 OTP 的通用架构。

OTP 算法的核心可以用一个公式概括:

OTP = Hash(SharedSecret + MovingFactor)
  • SharedSecret(共享密钥) :又称种子密钥,在用户注册时由服务端生成,通过二维码或手动录入的方式存储在客户端设备中,服务端同样保留一份副本。这是 OTP 安全性的根基,必须严格保密。

  • MovingFactor(动态因子) :一个不断变化的输入参数,确保每次生成的密码不同。

  • Hash:通常是 HMAC(基于哈希的消息认证码)算法,如 HMAC-SHA-1、HMAC-SM3 等,负责将密钥和动态因子“混合”成一个固定长度的摘要,再经过截断(Truncate)得到最终的 6~8 位数字口令-。

动态因子类型的不同,造就了 HOTP、TOTP 和 OCRA 这三种主流算法。

三、HOTP:基于计数器的 OTP 鼻祖

3.1 算法概述

HOTP(HMAC-Based One-Time Password) 是 OTP 家族的元老,由 VeriSign 的 D. M'Raihi 等人于 2005 年提交为 RFC 4226,是 OATH(Open AuTHentication)倡议的重要成果之一,旨在为技术社区提供一个可以自由分发和互操作的通用算法-2。HOTP 的核心思路极其简洁:用一个计数器(Counter) 作为动态因子,双方各自维护这个计数器的值,每次认证成功后同时递增。

HOTP 的生成公式如下:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))

其中 K 是共享密钥,C 是一个 64 位的整数型计数器值。每次用户请求新口令时,客户端计数器递增,服务端也在每次认证成功后同步递增,确保双方计数器状态一致。

3.2 核心处理流程

HOTP 的完整处理流程分为三个阶段,以标准的 6 位数字口令为例-:

  1. HMAC 计算:使用共享密钥 K 和计数器值 C(编码为 8 字节大端序),以 HMAC-SHA-1 算法生成一个 20 字节(160 位)的摘要。在 RFC 4226 标准定义中,HOTP 仅限定使用 SHA-1,但许多扩展实现支持 SHA-256 和 SHA-512。

  2. 动态截断(Dynamic Truncation) :从 20 字节的 HMAC 结果中提取 4 个连续字节。具体做法是取摘要的最后一个字节的低 4 位作为偏移量(Offset),从该偏移位置开始读取 4 个字节。

  3. 生成最终口令:将截取出的 4 字节(32 位)整数去掉最高位(& 0x7FFFFFFF),得到 31 位整数,最后取模 10^Digits(默认 10^6)得到 6 位数字口令。

Code = (last_byte & 0x0F)
DynamicCode = HMAC[Code:Code+4]
OTP = (DynamicCode & 0x7FFFFFFF) % 10^Digits

3.3 优点与局限性

HOTP 的最大优点是无需时间同步,因此非常适用于那些没有内置时钟的硬件令牌或纯离线场景。此外,HOTP 不依赖网络连接,可以在完全离线的设备上独立运行。

但 HOTP 的缺点同样明显:

  • 计数器失步问题:如果用户在不联网的情况下连续按压硬件令牌多次,客户端计数器会超前于服务端,导致后续认证失败。例如,用户连续生成 3 次口令但都未使用,服务端的计数器仍停留在原始值,双方状态便出现偏差。RFC 4226 中定义了“重同步窗口”机制(Resync Range),服务端可以在一定范围内(如 10 次)主动搜索匹配的计数器值来解决这一问题,但这一机制本身也带来了额外的安全考量。

  • 口令长期有效风险:由于 HOTP 口令本身没有时间有效期,一旦被截获,攻击者可以随时使用,直到该计数器被消费为止。

  • 服务器需要维护状态:每个用户的服务端都必须持久化存储当前的计数器值,每次成功认证后需要更新数据库,这在高并发场景下会带来额外的写入开销-。

  • 防重放依赖服务端记录:必须记录上一次成功认证的计数器,否则无法防止重放攻击-。

3.4 适用场景

尽管 TOTP 在移动端认证中更为流行,HOTP 仍有其独特的应用空间:硬件令牌、纯离线设备、金融 POS 终端、物理访问控制系统,以及那些无法保证设备时间准确性的嵌入式系统。

四、TOTP:基于时间的 OTP 现代标准

4.1 算法概述

TOTP(Time-Based One-Time Password) 是 HOTP 的直接进化版本,于 2011 年被接纳为 RFC 6238 标准-。顾名思义,TOTP 将 HOTP 中的计数器替换为时间戳,从而彻底解决了计数器同步问题。TOTP 已成为主动开放认证的基石,被广泛用于 Google Authenticator、Microsoft Authenticator 等双因素认证系统以及众多多因子认证方案中。

TOTP 可以看作是 HOTP 的一个具体场景化实现:

TOTP(K, T) = HOTP(K, T) = Truncate(HMAC-SHA-1(K, T))

但这里的 T 不再是简单的计数器,而是一个基于时间计算出的时间窗口编号

4.2 时间窗口:TOTP 的核心机制

TOTP 的独特性在于它的时间处理方式:

  1. 计算时间窗口编号:将当前 Unix 时间戳(自 1970-01-01 以来的秒数)减去起始偏移时间 T0(通常为 0),再除以时间步长 X(默认 30 秒),向下取整得到 T

T = Floor((Current Unix time - T0) / X)

其中 X 是步长(默认 30 秒),T0 是 UTC 起始时间戳。例如,在 X = 30 时,Unix 时间 59 对应的 T 为 1,60 对应的 T 为 2。

  1. HMAC 与截断:将共享密钥 K 和 T(编码为 8 字节大端序)作为输入,与 HOTP 完全相同的步骤生成最终口令。由于 T 的变化频率完全由时间决定,客户端与服务端只要时钟同步,就能在同一个 30 秒窗口内独立计算出完全相同的口令。

4.3 离线工作能力

TOTP 的另一个重要特性是完全不依赖网络连接。之所以能在离线情况下生成新口令,是因为认证器 App 只需本地存储的共享密钥和本机系统时间,即可通过 HMAC 算法独立完成计算。整个 TOTP 过程是确定性加密机制,而非网络通信驱动的结果。这正是微信、支付宝等支付软件离线付款码的核心技术原理:当手机没有网络时,软件根据预设的算法、种子数据和当前时间生成二维码,收银台扫码后由云端服务端完成验签-。

4.4 时钟偏移容差

TOTP 依赖时间同步的特性也带来了一个实际挑战:用户设备和服务器的时钟不可能完全一致。网络延迟、设备时间设置差异、虚拟机漂移等因素都会导致“无效验证码”错误。RFC 6238 标准建议服务端在验证时可以接受当前时间窗口前后各一个步长的口令(即窗口容差 Window = ±1),以补偿合理范围内的时钟漂移。

具体实现上,服务端会计算 T-1TT+1 三个时间窗口的口令,只要用户提交的口令匹配其中任何一个,即可通过验证。但 ⚠️ 需要注意:窗口容差每增加 1,攻击面就会显著扩大(±1 覆盖约 90 秒有效窗口,±2 则扩大至 5 分钟),因此生产环境建议将窗口锁定为 1 甚至 0。对于持续存在的系统时钟偏差,应优先通过 NTP 服务同步服务端时钟,并引导用户校准设备时间。

4.5 TOTP 的 QR 码配置

你可能已经注意到,双因素认证设置的二维码扫描后,认证器 App 会自动配置好账户信息。实际上,这个二维码存储的是一个符合特定格式的 otpauth URI

otpauth://totp/Issuer:User?secret=K&digits=6&period=30&algorithm=SHA1

其中 secret 是 Base32 编码的共享密钥,digits 是口令长度(默认 6 位),period 是时间步长(默认 30 秒),algorithm 是 HMAC 的哈希算法(默认为 SHA-1)。

4.6 安全性考量

TOTP 比 HOTP 更安全的核心原因在于短有效期:每个口令仅在 30 秒窗口内有效,过期自动失效。因此,即使攻击者通过钓鱼或中间人手段截获了一个 TOTP 口令,也无法在窗口之后使用-。

然而,TOTP 的绝对安全性仍然依赖于以下几点:

  • 共享密钥的安全存储:无论是客户端还是服务端,密钥泄露即意味着 OTP 体系完全失效。

  • 服务端防重放:即使 TOTP 会过期,服务端仍需记录“最近使用过的时间窗口”,防止攻击者在同一窗口内重复提交截获的口令-。

  • 限流机制:由于 6 位口令的空间仅有 100 万种组合,攻击者可以在几秒内穷举。因此 RFC 4226 建议服务端必须对 OTP 认证尝试进行限流,将每秒尝试次数限制在极低范围。

4.7 开发常见错误与避坑指南

根据 Authgear 对 2026 年 TOTP 实现问题的分析,开发者在集成 TOTP 时最常犯以下错误:

  1. 时钟漂移(Clock Drift) :服务端未配置 NTP,或容器/虚拟机迁移后出现时钟偏移,导致客户端与服务端的时间窗口错位。解决方案是服务端启用 NTP 同步,并在验证逻辑中加入 ±1 窗口容差。

  2. 密钥格式错误secret 参数必须是 Base32 编码,但许多开发者错误地将其作为 ASCII 字符串直接使用,或错误地进行了 hex 解码。有效的 Base32 密钥仅包含字母 A-Z 和数字 2-7(以及可选的 = 填充符)。

  3. RFC 6238 参数不一致:服务端与客户端在 digits(默认 6 位)、period(默认 30 秒)和 algorithm(默认 SHA-1)三个参数上不一致,导致双方生成的代码永远无法匹配。除非有充分的兼容性测试,否则应坚持使用 RFC 标准默认值。

4.8 适用场景

TOTP 是当今最主流的 OTP 实现方式,广泛应用于:Web 应用的 MFA 双因素认证、移动端动态口令 App、微信/支付宝离线付款码、VPN 和企业系统的二次认证。

五、OCRA:挑战-应答 OTP 的高级形态

5.1 算法概述

OCRA(OATH Challenge-Response Algorithm) 是 OTP 家族中功能最强大的成员,2011 年正式发布为 RFC 6287。OCRA 不再局限于简单的“密钥 + 计数器/时间”模式,而是引入了挑战-应答机制,支持单向认证、双向认证以及交易签名等高级能力。它将 HOTP 的算法框架推广到了更通用的范式:除了共享密钥和计数器外,还可以灵活地加入多组可变输入参数-。

5.2 算法定义

OCRA 的定义在 HOTP 的基础上大幅扩展,一个 OCRA 响应通常依赖于以下可选的输入参数:

DataInput = {OCRASuite | 00 | C | Q | P | S | T}

其中:

  • OCRASuite:表示计算方式的标识符。

  • 00:固定的分隔字节。

  • C:8 字节无符号计数器(可选)。

  • Q必选):128 字节挑战数据,通常是由服务端生成的随机值。

  • P:用户的 PIN/密码的哈希值。

  • S:UTF-8 编码的会话信息。

  • T:时间步长计数器。

5.3 三种工作模式

OCRA 定义了多种灵活的工作模式,覆盖不同安全级别的需求。

单向挑战-应答(One-Way Challenge-Response) :服务端生成一个随机挑战 Q 发送给客户端,客户端利用共享密钥计算出响应值并返回。服务端独立计算并与客户端响应比对。此模式可以确保客户端持有合法密钥,常用于系统登录认证。

双向认证(Mutual Challenge-Response) :在单向认证的基础上,客户端也用类似的机制验证服务端的身份。这种模式适用于高安全性场景,例如服务器向客户端推送敏感更新时,客户端需要先确认服务器的合法性,避免下载被篡改的恶意版本。

交易签名(Plain Signature) :挑战值 Q 直接由交易数据(如转账金额、收款账号)的哈希值派生而来。客户端使用共享密钥对交易数据生成一次性签名,服务端独立计算并比对。这种方式不仅验证了用户身份,更验证了交易内容的完整性,有效防范中间人篡改交易信息。该机制是当前对抗中间人攻击和网上银行“不正当汇款”的最有效措施之一-。

5.4 核心优势与局限性

OCRA 的核心优势在于:

  • 灵活的输入组合:可结合时间、计数器、会话信息、交易数据等多种因子,实现场景化的一次性密码。

  • 双向认证能力:服务端与客户端可以相互验证身份,增强通信安全性。

  • 交易签名能力:通过将交易数据嵌入挑战值,实现“所见即所签”,有效抵御中间人篡改交易内容。

但 OCRA 的局限性同样明显:实现复杂度较高,需要客户端具备一定的计算能力(如 EMV 银行卡芯片、手机安全应用);且标准化程度和生态成熟度远不及 TOTP,在普通 Web 应用中使用较少。

5.5 适用场景

OCRA 主要应用于高风险金融交易场景,例如网上银行大额转账时要求用户通过硬件令牌或手机 App 对交易数据进行签名确认-;金融 IC 卡内嵌的交易签名认证;以及企业 VPN 的强身份认证。近年来,隐私IDEA 等开源认证系统也逐步加入了 OCRA Token 的支持,通过挑战-应答机制完成对交易数据的数字签名-。

六、国密 OTP:SM 系列与动态口令的融合

随着《密码法》和等保 2.0 的全面实施,关键信息基础设施逐步要求使用国密算法替换国际算法,OTP 领域也不例外。目前国密 OTP 主要有两种融合路径。

6.1 国密 OTP 标准体系概览

国密 OTP 并非单一算法,而是一套融合 SM2/SM3/SM4/ZUC 等算法的完整技术体系,涵盖以下核心技术组件:

国密组件 在 OTP 体系中的角色 典型功能
SM3 哈希 一次性口令生成的核心哈希函数 替代 HMAC-SHA-1,生成口令摘要
SM4 对称加密 短信/通信信道的保护 加密传输 OTP 验证码,防信道劫持
SM2 非对称 种子密钥的安全分发与存储 服务器与客户端间建立安全密钥通道
ZUC 序列密码 实时通信中的一次性加密 4G/5G 通信链路中的动态口令加密
SM9 标识密码 大规模设备的动态凭证管理 物联网场景的“无证书”动态令牌
随机数发生器(国家审批) 种子密钥的安全生成 确保密钥不可预测,通过国密局检测

6.2 基于 SM3 的 TOTP 实现

国密标准中目前尚未专门定义 OTP 算法,但通过替换底层哈希函数,完全可以将 TOTP 改造为符合国密规范的实现。基本的实现步骤为:

  1. 生成密钥:服务端随机生成一个长字符串(如 64 字节),调用 SM3-KDF 派生函数生成最终密钥,并转换为 Base32 编码。

  2. 二维码配置:生成 otpauth URL 时,设置 algorithm=SM3,供支持 SM3 的认证器 App 扫描绑定。

  3. 验证逻辑:服务端支持 SM3 动态密码的生成与验证,并允许前后若干时间窗口的密码验证通过(窗口容差机制)。

在手机端,可以通过 GmSSL-JS 中的 sm3.js 实现 SM3-HMAC 计算,并集成 Base32 解码库来解析二维码密钥。支持 SM3 的 otpauth URL 格式与标准 TOTP 完全相同,仅需将 algorithm 参数改为 SM3。

6.3 SM4 在 OTP 通信保护中的应用

除了 TOTP 本身的哈希计算,国密算法更广泛的应用在于对 OTP 的传输通道进行加密。以医疗信息系统为例,短信验证码在传输过程中易被伪基站、SS7 协议漏洞或恶意 App 拦截。解决方案是:

  • 部署 SM4 对称加密(通常使用 CBC 模式)对 OTP 验证码内容进行加密后再封装为短信载荷,服务端接收后使用硬件密码机解密校验。

  • 加密前添加时间戳 + 随机盐值,防止重放攻击。

  • 在铁路信息化系统、堡垒机等场景中,OTP 双因子认证系统结合 SM4 国密算法,实现时效限制、抗穷举攻击、不可复制、一次性认证等安全特性-。

6.4 SM2 在 OTP 密钥保护中的应用

在动态口令体系中,种子密钥是安全性的核心。实践中通常将 OTP 认证服务器与硬件密码机相结合,采用 SM2 非对称加密对种子密钥进行加密保护,确保即使在服务器遭到入侵的情况下,密钥仍然无法被窃取-。四川农商银行等金融机构的 OTP 系统已在招投标要求中明确提出:口令生成需使用国密算法,支持时间型、事件型、挑战型等多种口令类型,并采用 SM2/SM3/SM4 套件,符合等保 2.0 和密评的合规要求-。

6.5 国密 OTP 的合规与生态现状

在监管层面,动态口令认证系统若要满足国密合规要求,必须使用经国家密码管理局审批的硬件密码模块或密码卡,与服务器协同完成密钥的存储和口令验证计算-。在生态层面,飞天诚信等厂商已推出支持国密算法的动态口令身份认证系统 OTP Server,提供手机令牌、硬件令牌等多种形式,集成 SM2/SM3/SM4 算法套件,已广泛应用于金融、政务、医疗等领域。

七、OTP 家族横向对比与选型指南

7.1 HOTP vs TOTP vs OCRA 综合对比

特性 HOTP TOTP OCRA
动态因子 递增计数器 Unix 时间窗口 挑战值(+计数器/时间等)
是否需要时间同步 是(需 NTP) 可选
需要服务端维护状态 是(计数器) 否(可无状态) 是(计数器等)
口令有效期 无期限,直到被使用 30-60 秒自动过期 挑战绑定,一次有效
支持双向认证
支持交易签名
抗钓鱼/中间人能力 弱(仅验身份) 强(交易数据绑定)
实现复杂度
生态成熟度 极高
典型应用 硬件令牌、离线设备 Web/Mobile MFA 银行交易签名

7.2 选型决策树

选择 OTP 方案
│
├─ 需要抵抗中间人篡改交易内容(如大额转账签名)?
│   └─ 是 → 使用 OCRA 交易签名模式
│
├─ 设备可能无法保持时间同步(如纯离线硬件令牌)?
│   └─ 是 → 使用 HOTP(配置合理重同步窗口)
│
├─ 是常规 Web/移动端双因素认证场景?
│   └─ 是 → 使用 TOTP(行业标准,最成熟)
│
└─ 需要满足中国等保/密评合规要求?
    └─ 是 → TOTP + SM3 哈希(GM/T 系列)

7.3 安全性分级建议

安全等级 推荐方案 典型场景
基础级 TOTP(6位,window=0) 普通 Web 应用、社区论坛
标准级 TOTP(6位,window=1)+ 限流 + 防重放 企业系统、VPN
增强级 TOTP(8位)或 HOTP + 硬件令牌 政务系统、中等额度交易
高保级 OCRA 交易签名 + 国密 SM2/SM3 大额银行转账、电子签名

八、OTP 的局限性与未来展望

8.1 OTP 的主要安全局限

尽管 OTP 比静态密码安全得多,但它仍然存在以下不可忽视的弱点:

  • 中间人攻击(MITM) :攻击者可以搭建钓鱼网站实时截获用户输入的 TOTP 口令,并立即转发给真实服务端完成认证——在这种攻击模式下,TOTP 的 30 秒有效期并不能起到有效防护。

  • SIM 卡劫持:短信 OTP 极易被攻击者通过社会工程学手段劫持或复制 SIM 卡后截获。

  • 设备丢失风险:若手机或硬件令牌丢失且未设置锁屏密码,共享密钥和 TOTP 生成器将完全暴露。

  • 社会工程学攻击:攻击者可伪装成客服诱骗用户提供当前 OTP 码。

  • 小额安全风险:与离线支付中单笔限额的逻辑相似,OTP 仅能验证“当前持有什么”,无法验证“当前是谁”。

8.2 2026 年的趋势:无密码认证与 OTP 的演变

进入 2026 年,Passkey(FIDO2/WebAuthn)已成为高安全或高频登录场景的主流无密码认证方案,广泛采用基于公钥密码学的认证方式:用户设备生成公私钥对,私钥永不离设备,服务端仅持有公钥,从而彻底阻断网络钓鱼攻击-。

那么,在 Passkey 逐步普及的时代,OTP 还有存在的意义吗?

答案是肯定的。在 2026 年的身份认证体系中,OTP 并未消失,而是被重新定位为关键的“备胎”角色

  • MFA 的降级备用:当用户无法使用生物识别或安全密钥时,OTP 作为备用的第二认证因子;

  • 一次性操作验证:Passkey 承担“登录认证”后,OTP 仍广泛用于“敏感操作确认”(如修改密码、转账确认);

  • 低安全等级接入:在 IoT 设备、遗留系统或政府身份认证等 Passkey 覆盖不足的场景,OTP 依然是主要选择。

Visa、Mastercard 等支付网络正在推动 Secure Payment Confirmation 与 Passkey 方案融合,未来在结账流程中,Passkey 将取代 OTP 成为默认的支付凭证-。

九、总结

OTP 家族从 2005 年的 HOTP(RFC 4226)发展到 2011 年的 TOTP(RFC 6238)和 OCRA(RFC 6287),构成了一个完整的一次性密码技术谱系。HOTP 以计数器为核心,简单可靠但存在状态同步问题;TOTP 以时间为核心,解决了同步难题,凭借离线工作能力和极低的接入成本成为 MFA 领域的绝对主力;OCRA 则以挑战-应答为特色,支持双向认证和交易签名,在高风险的金融场景中守护着“最后一公里”的安全。

与此同时,国密 OTP 以 SM3 哈希算法为核心,融合 SM4 加密传输和 SM2 密钥保护,正在满足日益迫切的合规需求。2024 年之后,OTP 的角色正在从“主要认证手段”演变为“降级备用方案和一次性操作验证器”。了解 OTP 家族的算法原理、适用场景和工程陷阱,是每一位安全开发者的必备功课。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐