作为一个强迫症,我希望我能用统一的APP管理我的一次性密码,而公司提供的宁盾一次性验证码,却只能用宁盾令牌管理。不能使用统一管理工具管理,这让强迫症怎么办,还需要多下载一个APP。经过我的研究,发现宁盾是使用标准TOTP算法生成一次性密码的,现在把它提供的种子密钥加工成符合otpauth规范的地址就可以由其它应用管理了。

获取宁盾二维码内容
绑定宁盾令牌时,解码这个二维码,获得文本
1
| http://mtc.ndkey.com/mtc/appDownload/index.html#eyJ2ZXJzaW9uIjoxLCJzZXJ2aWNlSWQiOiJzZXJ2aWNlSWQiLCJjb21wYW55TmFtZSI6IuWFrOWPuOWQjSIsImFjdGl2YXRpb25NZXRob2QiOjEsImV4cGlyZVRpbWUiOjE1MTExMTY5NjQzNDUsInRva2VuIjp7InNlcmlhbCI6IjEyMzQ1NiIsInNlZWQiOiI0ODY1NmM2YzZmMjFkZWFkYmVlZiIsInRpbWVTdGVwIjo2MCwicGFzc3dvcmRMZW5ndGgiOjYsImV4cGlyZVRpbWUiOjIyMTE0NTIxNjEwMDB9fQ
|
这个文本是一个url,获取这个url中#后的部分,将这部分使用base64解码。如果不能解码,在后面追加一个=
1
| eyJ2ZXJzaW9uIjoxLCJzZXJ2aWNlSWQiOiJzZXJ2aWNlSWQiLCJjb21wYW55TmFtZSI6IuWFrOWPuOWQjSIsImFjdGl2YXRpb25NZXRob2QiOjEsImV4cGlyZVRpbWUiOjE1MTExMTY5NjQzNDUsInRva2VuIjp7InNlcmlhbCI6IjEyMzQ1NiIsInNlZWQiOiI0ODY1NmM2YzZmMjFkZWFkYmVlZiIsInRpbWVTdGVwIjo2MCwicGFzc3dvcmRMZW5ndGgiOjYsImV4cGlyZVRpbWUiOjIyMTE0NTIxNjEwMDB9fQ
|
解码后可以得到一个json串,如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| {
"version": 1,
"serviceId": "serviceId",
"companyName": "公司名",
"activationMethod": 1,
"expireTime": 1511116964345,
"token": {
"serial": "123456",
"seed": "48656c6c6f21deadbeef",
"timeStep": 60,
"passwordLength": 6,
"expireTime": 2211452161000
}
}
|
重要字段说明:
token.seed
用于生成一次性密码的key
token.timeStep
一次性密码的有效期,单位秒
token.passwordLength
密码长度
这几个字段再后面会用到
生成secret
seed是一个hex string格式的种子,需要处理成secret才能使用
先将seed由hex string解密binary,再进行base32加密,得到的值就是secret
使用shell处理
1
| echo '48656c6c6f21deadbeef' |xxd -r -p | base32
|
使用java处理
1
2
| //cn.hutool:hutool-core:4.6.6
String secret = Base32.encode(HexUtil.decodeHex("48656c6c6f21deadbeef"));
|
生成otpauth url
栗子
1
| otpauth://totp/$用户名?secret=$secret]&issuer=$公司&algorithm=SHA1&digits=6&period=60
|
$用户名
处可以替换成你的账户名
$secret
替换为上一步得到的值
$公司
替换为公司名
algorithm
不需要动,默认用SHA1算法
digits
密码长度,替换为上文中的token.passwordLength
period
一次性密码有效期,替换为上文中的token.timeStep
得到的最终url可以直接粘贴到谷歌令牌、微软令牌、1Password等软件使用。也可以生成二维码扫描
终极命令
/tmp/abc
是二维码获取到的文本
1
2
3
4
5
6
7
8
9
| cat /tmp/abc \
| awk -F# '{printf "%s=",$2}' \
| base64 -d \
| jq .token.seed -r \
| xxd -r -p \
| base32 \
| awk '{printf "otpauth://totp/[用户名]?secret=%s&issuer=[公司]&algorithm=SHA1&digits=6&period=60",$1}' \
| qrencode -o - \
| open -f -a Preview
|
参考文档