安当OTP:国密SM3动态口令改造指南,从HMAC-SHA1到信创密评合规的落地路径
一、一个被长期忽略的合规盲区动态口令几乎是企业做双因素认证的标配。它的部署成本低、用户学习成本几乎为零、不需要改造业务系统因此在堡垒机、云桌面、远程接入、业务系统等场景中被大量使用。但也正因为太常用很多团队把它当成一个已经解决的问题直到密评或信创验收时才被一记闷棍敲醒你这套动态口令底层哈希用的是什么算法很多团队在百度搜索国密动态口令方案时真正想确认的其实只有一件事现在跑得好好的那套动态口令能不能直接改个配置项就变成国密的还是要推倒重来。答案是——服务端改起来不算难难的是客户端令牌、存量用户和兼容性。现实情况是这样的市面上绝大多数动态口令系统无论是商业产品还是开源实现默认算法都是 HMAC-SHA1。它是国际标准文档中定义的默认算法主流验证器应用谷歌验证器、微软验证器、各类手机令牌也都以它为实现基准。这套体系在纯互联网场景下没问题但一旦进入政务、金融、能源、交通等需要过商用密码应用安全性评估的场景或者进入信创替代的验收范围就立刻暴露出三个问题第一算法不在合规目录内。国内密码应用相关法规与标准要求涉及密码应用的信息系统应当使用列入商用密码目录的算法。SHA1 本身在国际上早已被认定为不安全碰撞攻击已被实际验证更不可能出现在合规目录里。第二密码运算未在合规密码产品内完成。密评关注的是运算在哪儿做、密钥在哪儿存、算法是否可控。大量动态口令实现是把种子以明文或简单加密形式存在关系型数据库里验算时在应用服务器内存里做 HMAC 运算整个链路既没有合规算法也没有合规密码产品承载。第三整改窗口往往很紧。密评整改通常有明确时间节点而动态口令牵扯到每一个最终用户的令牌是典型的牵一发动全身。如果没有提前规划双算法并存与分批换发很容易变成集中停机切换用户体验和运维压力都不小。所以真正要做的不是加一个 SM3 选项而是把动态口令系统的算法基座、密钥保护、令牌形态和迁移路径整体重新设计一遍。下面逐层展开。二、先定位哈希算法在 TOTP 里到底处于哪一步为了避免把这篇文章写成 TOTP 原理科普这里只精确指出算法改造要动的那一步。标准 TOTP 的计算可以拆成四步第一步把当前 Unix 时间按步长换算成计数器值counter floor((当前时间 - 起始时间) / 步长)步长通常为 30 秒。第二步把计数器值序列化为 8 字节大端整数作为消息。第三步用共享密钥种子对该消息做 HMAC 运算得到一个消息认证码。这一步是整个 TOTP 里唯一用到哈希算法的地方。第四步动态截断取消息认证码最后一个字节的低 4 位作为偏移量从该偏移处取 4 个字节屏蔽最高位后组成一个 31 位整数再对 10 的 N 次幂取模得到 N 位数字口令常见 6 位或 8 位。也就是说算法改造的切口非常集中把第三步 HMAC 里使用的哈希原语从 SHA1 换成 SM3其余四步的结构可以完全不动。这既是好消息——改动面小也是需要注意的地方——因为改动面小很容易被实现者轻率处理从而埋下兼容性隐患。三、为什么 HMAC-SHA1 在信创与密评场景下不合规把理由讲透需要区分三件事。其一SHA1 不是合规算法。我国商用密码算法体系中杂凑算法对应的是 SM3。SM3 输出长度 256 位其设计结构Merkle-Damgård 结构搭配特定消息扩展与压缩函数与国际上的 SHA-2 系列有相似的安全目标但在消息扩展、常数选取、布尔函数与置换上均有独立设计属于我国自主设计的杂凑算法。在需要过密评的系统中杂凑运算使用 SM3 是硬性要求SHA1 不被接受。其二SHA1 本身在密码学上已被攻破。学术界已经公开了 SHA1 的实际碰撞实例虽然针对 HMAC-SHA1 的实用攻击目前仍主要停留在理论层面但对于认证系统而言使用一个已被判定不安全的原语本身就是不可接受的选型合规测评中也不可能被放行。这一点与是否已被实际攻破无关而是算法生命周期管理的基本要求。其三信创验收要求算法自主可控。信创的核心是自主可控而自主可控在密码层面最直接的体现就是算法自主。一个跑在国产 CPU 和国产操作系统上、用国产数据库存储的系统如果身份鉴别环节仍在调用 SHA1整体链条就存在明显的断点验收时很难自圆其说。需要补充一点仅仅把哈希换成 SHA256 或 SHA512 也不解决合规问题。SHA-2 系列同样不是我国商用密码算法目录中的算法。有些团队在整改时用升级到 SHA256来应对这在密评中依然是不符合项。整改的唯一正确方向是 SM3以及在密钥保护与非对称环节配套使用 SM2、SM4。四、国密 OTP 的算法改造用 SM3 重构 HMACHMAC 的结构本身是与具体哈希算法解耦的它定义了一套通用构造HMAC(K, m) H((K xor opad) || H((K xor ipad) || m))其中 K’ 是密钥经过填充或哈希处理后得到的定长密钥ipad 与 opad 是两个固定填充常数H 是任意哈希函数。因此把 H 替换为 SM3就得到了 HMAC-SM3。在具体实现上有三个参数必须精确设定否则不同实现之间算出来的口令不一致这是国密 OTP 落地时最常见的事故来源。分组长度 B。HMAC 中密钥填充使用的分组长度应当取所使用哈希算法的输入分组长度。SM3 的输入分组为 512 位即 64 字节。这一点与 SHA-256 相同实现时不要误用 SM3 的输出长度。输出长度 L。SM3 输出 256 位即 32 字节。这比 SHA1 的 20 字节更长动态截断时可用的字节空间更大安全性上更宽裕。动态截断规则。建议严格沿用原有的动态截断规则取输出最后一个字节的低 4 位作为偏移量从偏移处取 4 字节屏蔽最高位与 0x7F 做与运算后组成 31 位整数再取模得到指定位数的口令。这样改造后的系统在截断逻辑上与存量实现完全一致便于同一套服务端同时支持两种算法。下面是一段参考实现示意代码仅用于说明计算流程deftotp(seed:bytes,unix_time:int,digits:int6,period:int30,t0:int0)-str:counter(unix_time-t0)//period msgcounter.to_bytes(8,big)# mac HMAC-SM3(seed, msg)分组长度 64 字节输出 32 字节machmac_sm3(seed,msg)offsetmac[-1]0x0Fbin_code((mac[offset]0x7F)24)\|((mac[offset1]0xFF)16)\|((mac[offset2]0xFF)8)\|(mac[offset3]0xFF)returnstr(bin_code%(10**digits)).zfill(digits)这段代码里唯一与国密相关的就是hmac_sm3这一个函数其余逻辑与常规实现完全一致。这也说明改造的技术难度并不高真正的工程量在两端适配与迁移。以安当OTP为例其服务端同时支持 SHA1、SHA224、SHA256、SHA384、SHA512 与 SM3 多种算法种子支持 base32 与十六进制两种编码格式因此国密改造可以在同一套服务端内以算法策略的形式配置而不是另起一套系统。五、改造涉及的两端与兼容性风险动态口令是典型的两端系统只改一端必然失败。5.1 服务端需要改什么服务端的核心职责是种子管理与验算。改造点包括算法策略模型。在用户令牌记录中增加算法字段使每条令牌记录都能明确标注自己使用的算法、位数、步长、允许窗口。这样同一个服务端可以同时服务 SHA1 存量用户与 SM3 新用户。密码运算模块。引入 SM3 与 HMAC-SM3 实现。这里有一个关键决策SM3 运算应当尽可能下沉到合规密码产品或密码模块内完成而不是在应用层用一段纯软件代码算。密评中运算是否在合规密码产品内完成是重要的评分点。种子保护。种子必须脱离明文存储改为由密码模块加密保护或直接在硬件密码模块内生成与保存见第七节。验算接口兼容。服务端对外提供的验算接口无论是接口服务还是传统的远程认证协议接口不应因算法改变而改变调用方式算法选择应当对用户与应用透明由服务端按令牌记录自动匹配。5.2 客户端令牌需要改什么客户端是改造的真正难点因为它直接面对最终用户。手机令牌应用。通用验证器应用只实现了标准中定义的算法集合不包含 SM3。因此国密 OTP 需要专用的手机令牌应用或使用支持国密算法的商业令牌应用。专用应用需要内置国密算法库并处理好国产移动操作系统与国产芯片架构的适配。硬件令牌。硬件令牌需要选择支持国密算法的型号。选型时要确认令牌内部是否真正实现了 SM3 运算、种子写入后能否不可导出、是否支持种子灌装与批量初始化、电池寿命与时钟精度是否满足要求。小程序或轻量令牌。如果采用小程序形态的令牌需要确认运行环境能否调用国密算法能力否则仍会在算法层退回国际算法改造成果得而复失。5.3 兼容性风险清单风险点表现应对方式通用验证器不支持国密算法用户扫码后算出的口令与服务端不一致国密用户统一使用专用令牌应用或硬件令牌注册入口与普通入口分离两端分组长度或截断规则实现不一致同一算法下口令仍不匹配制定统一算法规范文档两端以同一组测试向量交叉验证种子编码格式差异扫码导入后种子被错误解码统一采用 base32 或十六进制并在注册流程中做一次校验性验算算法字段缺失导致网关错配存量用户被强制按新算法验算而全部失败升级前为每条存量令牌回填算法字段默认按原算法硬件令牌型号混杂同一批用户拿到不同算法的令牌按批次管理令牌型号与算法映射台账与后台记录一一对应第三方系统内置了自有验算逻辑业务系统绕过认证服务自行验算收口验算入口禁止业务侧自行实现验算六、种子的生成、分发、存储与保护种子共享密钥是动态口令系统里唯一的长期秘密它的保护水平直接决定整个系统的安全性也是密评中的重点检查项。很多团队在百度搜索动态口令系统安全时真正想确认的就是种子到底存在哪儿、谁看得见。生成。种子应当由合规的随机数发生器产生随机数质量必须可举证。推荐做法是在硬件密码模块内直接生成种子生成过程与结果都不离开密码模块边界。种子长度建议不小于 128 位与安全强度相匹配。分发。分发是泄露风险最高的环节。常见方式有三种其一是二维码分发服务端生成包含种子的注册二维码管理员或用户扫码导入其二是种子文件分发以加密文件形式下发配合独立信道传递解密口令其三是硬件令牌预灌装由厂商在受控环境中把种子直接写入令牌同时把种子密文交付给服务端导入。三者中硬件预灌装的安全边界最完整二维码方式最便捷可按用户群体的安全等级分档采用。存储。明文存库是必须杜绝的做法。合规的存储方式有两种一是由密钥管理系统或硬件密码模块生成并保存种子应用侧只保存种子的句柄或标识验算时调用密码模块完成运算二是由应用侧保存种子的密文加解密密钥由密钥管理系统统一管理密钥本身不以明文形式出现在应用侧。无论哪种方式目标都是一致的种子不以明文形式出现在数据库、日志、备份和内存转储中。使用。验算时理想状态是种子不离开密码模块由密码模块内部完成 HMAC-SM3 运算并只返回运算结果。如果工程上暂时做不到至少要做到取种子密文、解密、运算、立即清零的最小暴露窗口并杜绝把种子写入任何形式的日志。销毁。用户令牌注销、令牌换发、员工离职时不仅要删除应用侧记录还要同步销毁密码模块中对应的密钥对象并留存销毁记录。七、时间同步、步长窗口与漂移校准动态口令依赖时间时间问题是最常见的用户报障来源国密改造后这部分逻辑不变但仍需系统化设计。步长与窗口。步长通常取 30 秒。服务端验算时不会只比对当前步长的口令而是会向前向后各看若干个窗口。典型配置是前后各一个窗口等效于给予用户约正负 30 到 60 秒的容错。窗口开得越大用户体验越好但被暴力猜测的成功概率也越高因此不建议盲目放大同时必须配合失败次数限制与锁定策略。口令重试限制。同一个账号在短时间内连续验算失败达到阈值后应当锁定一段时间或直接锁定令牌。这是因为 6 位数字口令的搜索空间只有一百万如果没有重试限制在线暴力破解是有现实可行性的。漂移校准。硬件令牌的晶振会随温度与老化产生漂移长期运行后累计误差可能达到数分钟导致口令全部失效。服务端应当记录每个令牌的漂移步数验算时若命中当前步长之后的第 N 个窗口则把该令牌的漂移值更新为 N后续验算自动带上这个偏移。漂移值应当有上限超过上限例如累计超过若干分钟则判定令牌时钟异常提示用户送修或换发。时间源。服务端必须接入可靠的时间同步源并且自身时间不得被随意修改。分布式的认证服务集群要保证节点间时间一致否则会出现在 A 节点能登录、在 B 节点不能登录的诡异现象。单次使用约束。口令在有效期内被成功使用后应当记录该步长已被消费禁止同一口令在同一窗口内重复使用。这能有效防御肩窥与中间人重放。八、密评中的证据点与测评口径这一节是很多技术团队最不熟悉、却直接决定能否通过的部分。动态口令在商用密码应用安全性评估中通常落在身份鉴别这一技术层面常见的测评关注点如下。算法合规性。测评会确认动态口令生成过程中使用的密码算法是否为合规算法。整改后的正确证据是SM3 用于杂凑运算SM2 用于需要非对称密码的环节如令牌注册时的挑战签名SM4 用于种子等敏感数据的存储与传输保护。要能提供算法调用路径的说明与实测验证。技术合规性。关键在于密码运算是否在合规密码产品内完成以及产品是否取得商用密码检测认证。使用取得认证的硬件密码模块或密码产品承载种子与运算是最直接的合规路径。密钥管理合规性。测评关注种子的生成、存储、分发、更新、销毁全生命周期是否受控是否存在明文存储、明文传输、越权访问等问题。需要提供密钥管理制度文件、技术实现说明与抽查验证。防护有效性。测评会验证动态口令是否真正构成第二因子例如拔掉令牌后是否无法登录、口令是否具备一次性、是否存在可绕过路径、失败锁定策略是否生效。测评口径上的一个常见分歧点是动态口令属于密码技术还是非密码的认证手段。如果动态口令系统完全没有使用密码算法例如某些基于查表的一次性口令本它就不属于密码技术应用无法计入密码应用的技术得分。反之一旦使用了 SM3 做杂凑运算它就明确属于密码技术应用需要完整接受算法、技术、密钥管理三个维度的检查。这一点在方案设计阶段就要与测评机构沟通确认避免整改完才发现口径理解不一致。九、存量 SHA 令牌的平滑替换路径改造最忌讳一次性切换。推荐分四阶段推进。阶段一能力准备。服务端完成 SM3 算法支持、算法字段建模、种子保护改造接入密钥管理系统或密码模块、专用令牌应用与国密硬件令牌选型。这一阶段对存量用户完全无感。阶段二双算法并存。服务端同时支持 SHA 系列与 SM3。新注册用户默认发放 SM3 令牌存量用户维持原算法不动。此阶段重点是跑通新链路验证两端一致性并积累运维经验。并存期建议不短于一个完整的换发周期。阶段三分批换发。按用户群体分批推进优先换发高权限账号系统管理员、运维人员、财务、其次是外部与远程访问用户、最后是内部普通用户。换发方式可以是用户自助重新注册扫码绑定新令牌也可以是集中发放硬件令牌。每批换发后要跟踪失败率与报障量确认稳定后再推进下一批。阶段四收敛下线。当存量 SHA 令牌占比降到可接受水平后设定一个截止日期届时停止 SHA 算法验算对仍未换发的用户提供线下的应急换发通道。截止日期要提前充分通知并保留管理侧的临时放行能力以应对特殊情况。在整个迁移过程中有两条经验特别重要。第一迁移台账要精确到人谁已换发、用的什么算法、什么令牌形态、什么时间。没有台账就无法确认收敛进度。第二永远保留逃生通道换发期间用户令牌失效是必然会发生的事必须提供经过身份核验的人工重置流程而这个流程本身也要有审批与审计。十、落地步骤与配置示例下面给出一个可操作的落地顺序。第一步梳理现状。盘点现有动态口令系统有多少用户、多少令牌、什么令牌形态、种子存在哪里、验算在哪做、对接了哪些业务系统。这一步的输出是一张现状表也是后续风险评估的输入。第二步确定目标架构。明确种子由谁保护密钥管理系统或硬件密码模块、SM3 运算在哪一层完成、令牌采用什么形态、是否保留双算法并存。第三步服务端改造。引入 SM3 与 HMAC-SM3 能力改造令牌记录模型接入种子保护机制改造验算接口使其按令牌记录自动匹配算法。第四步两端一致性验证。用统一的测试向量集验证服务端与各类令牌的算式一致性。测试向量应覆盖不同种子、不同时间点、不同位数以及跨步长边界的时间点。第五步试点运行。挑选一个小规模、可控的用户群例如安全团队自身试用 SM3 令牌观察一个完整周期。第六步分批换发与收敛。按第九节的四阶段推进。一个典型的令牌配置示例示意# 令牌策略配置示意otp:algorithm:SM3# 支持 SM3 / SHA1 / SHA256 / SHA512digits:6# 口令位数可选 6 或 8period:30# 时间步长单位秒window:1# 前后各允许的窗口数max_drift_steps:3# 允许的最大漂移步数max_attempts:5# 连续失败次数上限lock_seconds:300# 触发上限后的锁定时长seed_encoding:base32# 种子编码可选 base32 或十六进制seed_storage:kms# 种子由密钥管理系统保护应用侧仅存句柄one_time_use:true# 同一窗口内口令仅可使用一次这份配置的关键在于seed_storage与algorithm两项前者决定了种子是否真正受密码模块保护后者决定了算法是否合规。其余参数是通用工程参数按业务容忍度调整即可。十一、检查清单与算法对照国密改造检查清单检查项达标标准常见不达标情形杂凑算法动态口令生成使用 SM3仍是 SHA1或改成了 SHA256运算承载运算在合规密码产品或密码模块内完成应用服务器内存中纯软件实现种子生成由合规随机数发生器产生用普通随机函数生成种子种子存储加密存储或存于密码模块无明文数据库明文存储种子种子分发加密分发或硬件预灌装明文二维码长期有效、可重复扫描种子销毁令牌注销时同步销毁并留痕只删应用侧记录密码模块内残留算法字段每条令牌记录明确标注算法缺少算法字段升级后全部错配两端一致性通过统一测试向量交叉验证两端分组长度或截断规则不一致时间同步服务端接入可靠时间源集群时间一致节点间时间不一致导致偶发失败漂移校准有漂移记录与上限判定令牌漂移后永久失效只能换发重试限制有失败次数上限与锁定策略无限制存在在线暴力破解风险单次使用同一窗口内口令不可重复使用同一口令可重复通过验算迁移台账精确到人的换发进度记录无法确认存量收敛比例逃生通道有经审批的人工重置流程令牌失效后用户彻底无法登录算法对照表维度HMAC-SHA1HMAC-SHA256HMAC-SM3杂凑输出长度160 位256 位256 位HMAC 分组长度64 字节64 字节64 字节是否属商用密码算法否否是密评可用性不符合不符合符合通用验证器支持普遍支持普遍支持需专用令牌信创适配无自主可控要求无自主可控要求满足自主可控从这张表可以清楚看到整改的方向只有一条SM3。把 SHA1 升级成 SHA256 看似前进了一步但在合规维度上原地踏步。十二、常见问题与验证方法Q1直接把算法配置项改成 SM3用户手机上的通用验证器还能用吗不能。通用验证器不实现国密算法改完之后它算出的仍是旧算法的口令与服务端不匹配。国密用户必须换用支持 SM3 的专用令牌应用或硬件令牌这也是改造中最大的用户侧工作量。Q2能不能服务端算两套用户输哪个都算通过技术可行但强烈不建议。同时接受两种算法会让最弱的一环决定整体安全强度等同于没有整改且在密评中会被直接判定为不合规。正确的做法是双算法并存但按令牌记录严格匹配而不是对同一令牌放宽验算。Q3SM3 替换 SHA1 后口令位数和步长需要改吗不需要。SM3 输出 32 字节比 SHA1 的 20 字节更长动态截断时可用空间更充足6 位或 8 位口令、30 秒步长都可以保持不变。Q4硬件令牌的时钟漂移怎么处理服务端记录每个令牌的漂移步数验算时自动补偿超过漂移上限则判定令牌时钟异常提示送修或换发。同时服务端自身必须接入可靠时间源。Q5种子能不能放在数据库里用 SM4 加密就行这是可接受的过渡方案但不是最优解。更合规的做法是把种子放在硬件密码模块或密钥管理系统内应用侧只保存句柄验算时调用密码模块完成运算种子全程不出安全边界。Q6如何验证两端算法实现一致准备一组标准测试向量固定若干个种子、固定若干时间点、覆盖跨步长边界的临界值分别计算期望口令然后与服务端和令牌端的输出逐一比对。这是改造过程中必须做的一次性验证不能只靠扫个码试试能不能登录。Q7存量用户太多一次性换发不现实怎么办按第九节的四阶段推进关键是服务端具备按令牌记录匹配算法的能力使两种算法可以长期并存从而把换发节奏完全掌握在自己手里。Q8动态口令用的种子和 UKey 里的私钥保护要求一样吗两者的保密性要求同等重要区别在载体。UKey 的私钥天然不可导出由硬件保证动态口令的种子是共享密钥服务端也必须持有因此必须借助密码模块或密钥管理系统来构造同等的保护边界。方案参考安当OTP是上海安当技术推出的动态口令产品可作为国密改造与信创合规场景的参考方案。其核心能力如下算法支持同时支持 SHA1、SHA224、SHA256、SHA384、SHA512 与 SM3便于存量国际算法令牌与国密令牌长期并存、分批替换。令牌形态支持手机令牌应用、硬件令牌与短信等多种形态手机令牌支持扫码注册可与主流验证器兼容使用国密场景则配套支持 SM3 的专用令牌。口令参数支持 30 秒时间步长默认 6 位口令可按安全策略调整位数与窗口容错。种子管理种子支持 base32 与十六进制编码可结合密钥管理系统实现种子的安全生成、存储与保护避免明文落库。对接方式支持远程认证协议接口与接口服务两种对接方式一套后台可同时服务多个应用系统业务侧改造量小。部署形态支持本地化部署与服务化订阅两种模式满足不同行业对数据驻留与运维模式的要求。用户自助支持用户自注册与自主绑定令牌可显著降低批量换发阶段的运维压力。在实施国密改造时建议按本文第十一步的检查清单逐项自评优先解决算法是否合规与种子是否受保护两项再推进令牌换发与收敛下线。