学校某系统使用宁盾令牌(Dkey Token)进行二步验证,想将其转换为标准TOTP两步验证导入BitWarden中统一管理。
关于TOTP
介绍TOTP:
- Time-based One Time Password,时间同步一次性密码。
- 客户端和服务端保存同一个Secret密钥,同时保持正确的时钟
- 每30s/60s基于时间和Secret密钥生成新的口令
关于Secret密钥:
The length of the shared secret MUST be at least 128 bits. This document RECOMMENDs a shared secret length of 160 bits.
在TOTP的URL中,
secret
参数包含共享的密钥,这个密钥是一个二进制数据。为了将它包含在URL中并确保URL友好,密钥会经过Base32编码。
抓包获取参数
在令牌绑定的页面上抓包,可以看到请求refreshMobileToken
接口,其中部分信息如下:
|
|
从二维码获取参数
同时解码二维码,得到如下url(关键信息已抹去):
https://mtc.ndkey.com/mtc/appDownload/index.html#eyJ2ZXJzaW9uIj****......****NjMxMDAwfX0
对#
后面的部分进行base64解码,得到如下json:
|
|
计算密钥
对于抓包得到的json请求,其中的seed
参数看起来像是经过base64编码的密钥。对其进行base64解码,得到二进制密钥,再进行base32编码,即可得到totp url中的secret。
对于二维码得到的json,其中的seed
参数为16进制表示的二进制密钥。对其进行hex解码,得到二进制密钥,再进行base32编码,即可得到totp url中的secret。
尝试以上两种方法,得到的secret是相同的
我使用这个网站进行编码/解码:CyberChef
使用这个工具进行base64解码时,需要取消勾选
Remove non-alphabet chars
拼接字符串
[USERNAME]
:用户名[SECRET]
:base32编码后的密钥,使用上述方法计算[DIGITS]
:密码长度,为得到的参数中的passwordLength
,我这里是6[PERIOD]
:过期时间,为得到的参数中的timeStep
,我这里是60
|
|
尝试
我这里拼接得到的字符串最终为:
|
|
将其填入BitWarden中,可以正确生成TOTP口令。