GmSSL中的totp

背景

越来越多的网站像Github一样开启了2次验证,给你生成一个6位的数字动态口令,这种就叫TOTP,通俗讲,就是基于时间的一次性动态口令。我在家里搭了个Alist文件服务器,也默认支持TOTP,不过我开了HTTPS,用的也不多,TOTP验证就关了。我为什么要看这个呢,上班的地方wifi使用了h3c e盾认证,里面使用了SM3计算口令,每次连wifi还得点开app,索性看看它是怎么计算的。

TOTP介绍

首先我们看一下Github二次验证,它会给我们一个二维码,让我们用Authenticator类似的软件扫一扫,然后就能添加。如果我们用别的软件扫,会得到一个如下的地址:(来源互联网的二维码)

otpauth://totp/GitHub:user?secret=MMJCO5MSOUN57MGT&issuer=GitHub

这里我们主要关注的是secret,128bit的key,其它参数都是用来在软件上显示的,其实你可以随意修改。软件会用secret + 时间值计算一个hash,并截取6位作为口令值。服务端校验时,通常会计算前一个或者后一个值,用来容错对比。

  • TOTP生成:TOTP(K,T) = Truncate(HMAC-HASH(K,T)),其中HASH=SHA-1/SHA-256/SHA-512

对上述参数做简单说明:

  1. K就是你的密钥,也就是secret
  2. T为时间因子,一般时间戳(秒) / 步长。如30s一刷新,那就是当前时间戳(秒) / 30。

GmSSL

otpauth://totp/lefo:lefo?secret=MMJCO5MSOUN57MGT&algorithm=sm3

GmSSL中,SM3 SM4算法可以用来生成一次性口令,日常使用中,也是一个链接生成的二维码,与常规totp的二维码无异,只是后面会跟一个参数用来标记使用sm3/sm4算法。但算法并不是替换就行,还多了两项参数。

  • GMOTP生成:GMOTP(K,T|C|Q)=Truncate(F(K,T|C|Q)),其中F=SM3/SM4

其中,C为事件因子,8字节整数。Q为挑战因子,4字节整数。均可省略。将这些参数拼接起来,再调用SM3/SM4算法。

国标GmSSL TOTP

全国标准信息公共服务平台有一项规范为《信息安全技术 动态口令密码应用技术规范》,内部介绍了SM3 SM4计算totp的方法,其中Truncate计算和常规totp计算也不一样。在常规totp中,是取最后4字节,但是在该规范中,32个字节分为8组,将所有4字节整数求和。

参数 规范中的扩展(推测)
参数为 K 和 T 参数为 K、T、C、Q
使用标准哈希算法(SHA-1、SHA-256) 使用国密算法
Truncate 步骤使用偏移量截取 4 字节 可能分组为 8 部分(S1-S8),通过计算决定截取部分