动态口令密码应用的技术原理与 GM/T 0021 标准深度解读:从 HOTP/TOTP 到国密算法实现

标准规范 · 2026-07-07

概述

动态密码(Dynamic Password),又称一次性密码(One-Time Password, OTP),是现代多因子认证(MFA)体系中最广泛部署的第二因子技术。与静态密码不同,动态口令每隔一定时间或每认证一次就变化一次,即使被截获也无法重复使用。

当前主流的 OTP 技术基于两个 IETF RFC 标准:RFC 4226(HOTP,基于 HMAC 的事件同步 OTP)和 RFC 6238(TOTP,基于时间同步的 OTP)。两者都采用 SHA-1 作为底层哈希算法,使用 6-8 位数字作为口令输出。

GM/T 0021《动态口令密码应用技术规范》是中华人民共和国密码行业标准,最早发布于 2012 年(GM/T 0021-2012),后在 2023 年更新(GM/T 0021-2023)。该标准针对国密合规场景,要求使用 SM3 或 SM4 算法替代 SHA-1,并对密钥管理、动态因子生成、截断函数等环节提出了严格要求。

本文将从工程实现角度,系统解析动态口令的技术原理,深入解读 GM/T 0021 的核心设计,并提供生产环境部署建议。

OTP 算法基础

核心概念模型

动态口令的生成基于三个核心要素:

种子密钥(Secret/Seed Key):服务端和客户端共享的对称密钥,通常以 Base32 编码或二维码形式分发给用户。种子的安全性是整个 OTP 体系的核心——种子泄露意味着 OTP 保护失效。

动态因子(Dynamic Factor)

  • HOTP 使用递增计数器(Counter),客户端每次生成口令后计数器 +1
  • TOTP 使用 Unix 时间戳除以时间步长(Time Step),通常步长为 30 秒
哈希运算:将种子密钥和动态因子输入哈希函数,产生固定长度的摘要。

截断函数(Truncation):从摘要中提取 4 字节,转换为 0-999999 范围的整数,再取模得到 6 位数字(可扩展至 7-8 位)。

国际标准:HOTP 与 TOTP

#### HOTP(RFC 4226)

HOTP 的核心公式:

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

其中:
- K:种子密钥(≥128 bit)
- C:8 字节大端递增计数器
- Truncate():从 HMAC 输出中提取 4 字节并转换为整数

截断函数详解:

注意 0x7F 掩码:防止符号位问题,确保结果为正整数。

#### TOTP(RFC 6238)

TOTP 建立在 HOTP 之上,将计数器替换为时间戳:

CODE
TOTP(K, T) = HOTP(K, T)

其中:
- T = floor((UnixTime - T0) / TimeStep)
- T0:起始 Unix 时间戳(通常 0,即 1970-01-01)
- TimeStep:时间步长(通常 30 秒)
- UnixTime:当前 Unix 时间(秒)

关键参数:

参数典型值说明
T00起始时间戳(UTC 1970-01-01 00:00:00)
TimeStep30s口令更新间隔
Digit6输出位数(或 8)
Look-ahead±1服务端向后查看的步数(容忍时钟漂移)

服务端的验证逻辑

服务端验证不仅仅是"比对当前值的 OTP 是否匹配",还需要处理客户端时钟漂移和计数器不同步:

GM/T 0021 标准对动态口令的特殊要求

算法选择:国密密码体系的必由之路

GM/T 0021 要求动态口令使用国密算法替代国际标准中的 SHA-1:

环节国际标准GM/T 0021 要求
哈希运算SHA-1SM3 密码杂凑算法
分组加密(可选)AESSM4 分组密码算法
MAC 运算HMAC自定义拼接杂凑或 SM4-CBC-MAC
SM3 算法的核心作用

GM/T 0021 中,动态口令的 SM3 国密实现并非使用 HMAC-SM3,而是采用种子密钥与动态因子拼接后直接进行 SM3 杂凑的方式:

CODE
OTP_SM3(K, F) = Truncate(SM3(K || F))

其中:
- K:种子密钥
- F:动态因子(计数器或时间戳)
- ||:拼接操作(具体拼接方式由标准定义,参考 GM/T 0021-2012 第 6.2 节)
注意:这种设计使得 GM/T 0021 的 SM3 实现与 HMAC-SM3 不等价。HMAC 使用 ipad/opad 进行密钥填充和两层哈希,而直接拼接只做一次杂凑。两者的安全性依赖不同的密码学假设。

密钥管理要求

GM/T 0021 对种子密钥的全生命周期提出了严格管理要求:

  • 密钥生成:种子密钥必须由密码随机数生成器(符合 GM/T 0005)产生,长度不小于 128 位(16 字节)
  • 密钥分发:种子密钥在服务端和客户端之间分发时,必须使用 SM2 密钥封装或 SM4 加密传输,明文不得出现在传输信道中
  • 密钥存储:服务端种子密钥应存储在密码机或安全介质中(参考 GM/T 0028 对应安全等级要求);客户端种子密钥存储在身份验证器安全区域或智能密码钥匙中
  • 密钥更新:种子密钥应定期更新,建议在以下情况下强制更新:用户挂失、设备更换、密码机重置
  • 密钥销毁:密钥生命周期结束后必须安全清零,防止残留数据被恢复

动态因子的安全要求

GM/T 0021 强调动态因子的不可预测性:

  • HOTP 计数器:计数器服务端必须单调递增,认证成功后立即更新,防止重放
  • TOTP 时间戳:时间戳必须通过可信时间源获取,服务端和客户端的时钟漂移容忍窗口不得配置过大(建议 ±2 个时间步)
  • 动态因子长度:动态因子至少应为 8 字节,确保足够的熵值

截断函数的设计

GM/T 0021 截断函数的设计思想与 RFC 4226 类似,但针对 SM3 输出做了适配:

CODE
SM3 输出为 32 字节(256 位),截断偏移量取值范围 0-27(最后 5 位)
取 4 字节(32 位),取低 31 位确保正整数

OTP = Code % 10^Digit
其中 Digit 通常为 6 或 8

国密 OTP 的工程实现

SM3-based TOTP 实现(伪代码)

以下伪代码展示 GM/T 0021 风格的国密 TOTP 生成逻辑,用于原理说明(非实际运行代码):

服务端重放攻击防护

TOTP 的重放防护是工程中的关键挑战。常见方案:

工程建议:方案二(步长单调递增)更适合高并发场景,避免了数据库写入已用 OTP 的性能开销。但在 TOTP 中需要处理合理的时钟漂移(用户设备时间偏差),建议允许 look_ahead = 1(即 ±30 秒),同时使用步长单调性确保同一窗口内的重放被拒绝。

国密认证产品生态

GM/T 0021 认证的动态口令产品

截至 2026 年,多家国内密码产品厂商的 OTP 产品已获得 GM/T 0021 认证,安全等级通常为二级或三级:

厂商产品型号安全等级证书编号示例
宁盾科技NDKEYTPASS V8.0安全二级GM013111420250947
天安电子TASS OTP安全二级GM013111420XXXXXXXX
众人科技JustKey OTP安全二级
产品形态

  • 软件身份验证器(手机 App):种子密钥加密存储在设备安全区(如 iOS Keychain、Android Keystore),通过 SM3/SM4 算法生成 OTP
  • 硬件动态令牌(显示设备):内置安全芯片执行国密算法,LCD 显示动态口令,防物理拆解设计
  • 智能密码钥匙(USB Key):符合 GM/T 0027 规范,执行 SM2 签名 + SM3 OTP 双重认证

与 GM/T 0016 的协同应用

GM/T 0016《智能密码钥匙密码应用接口规范》定义了智能密码钥匙的应用接口,厂商可基于此接口实现:

  • 密钥生成:在 Key 内部生成 SM2 密钥对,私钥不可导出
  • OTP 生成:在 Key 内部完成 SM3 哈希和截断,输出最终 OTP 到主机
  • 双因子认证:SM2 数字签名(证明 Key 持有)+ SM3 OTP(证明用户知道 PIN 码)

密钥派生与分散

密钥分散的概念

在大规模企业或金融系统中,为每个用户生成独立的种子密钥在管理上极为复杂。GM/T 0021 引入了密钥分散机制:

密钥分散的核心思想:从单一的根密钥派生出大量用户专属种子,系统只需保护根密钥的安全,而不需要为每用户存储独立的种子。

GM/T 0021 中的分散操作

根据标准原文(GM/T 0021-2012 第 6.3 节),分散操作通常采用以下方式:

CODE
分散种子 = SM3(根密钥 || 分散因子 || 分散标识)

其中:
- 根密钥:密码机内生成和存储的主密钥
- 分散因子:足够区分用户的标识(如手机号、用户编号、身份证号散列)
- 分散标识:区分不同应用或用途的固定字符串(如 "OTP-AUTH-v1")
- SM3 输出 32 字节,取前 16 字节作为 128 位种子密钥
安全要求:根密钥必须存储在符合 GM/T 0028 要求的密码机或安全介质中,分散运算也在密码机内完成,根密钥不可导出。

安全性分析与合规要求

抗重放攻击

动态口令天然具有抗重放特性(一次性使用),但工程实现中仍需防范以下攻击:

攻击类型攻击方式GM/T 0021 防护要求
重放攻击截获已使用的 OTP 再次提交服务端记录已用 OTP/步长
中间人攻击在网络信道中截获 OTP国密 TLS 传输加密(推荐 GM/T 0024)
暴力破解穷举所有可能的 OTP 值6 位数字限 10^6 种可能,服务端实施速率限制
种子泄露获取种子密钥根密钥存储在密码机内,不可导出

时钟漂移容忍

TOTP 的安全性依赖于服务端和客户端的时钟同步。实际工程中:

  • 服务端时钟:必须通过 NTP 协议与国家标准时间同步(建议精度 ±1 秒以内)
  • 客户端时钟:移动设备通常通过网络自动同步,但存在断网后时钟漂移的场景
  • 容忍窗口:look_ahead = ±1(即 ±30 秒)可覆盖绝大多数场景;增大到 ±2 会增加暴力破解风险

密评合规要点

根据密评实践经验,动态口令系统的合规检查重点:

  • 算法合规:必须使用 SM3 或 SM4,禁止使用 SHA-1(在高风险判定时,基于 SHA-1 的 OTP 会被判定为高风险)
  • 密钥管理合规:种子生成、分发、存储、使用、销毁各环节需有完整记录
  • 密码模块合规:动态口令生成模块需通过 GM/T 0028/0039 检测认证
  • 传输合规:服务端与验证器之间的种子分发需使用国密算法加密传输

总结

  • GM/T 0021 是国密 OTP 的标准基石:使用 SM3/SM4 替代 SHA-1,满足密评合规要求
  • 种子密钥安全是核心:根密钥存储在密码机内,通过密钥分散派生用户种子
  • 重放防护不能依赖算法本身:必须配合服务端的步长记录或 OTP 去重机制
  • 时钟同步是 TOTP 的生命线:建议部署 NTP 服务并监控时钟偏差
  • 与智能密码钥匙协同:SM2 签名 + SM3 OTP 提供硬件级双因子认证

参考来源

相关实践