google身份验证器&动态口令验证

1.为什么使用动态口令?

1
2
3
一般我们在登陆网站时,需要提供账号密码进行登陆验证。但是一单账号密码泄露,则账户存在很大的风险。
在此基础之上,有另外的方案:短信验证,邮件验证等等,但是都会存在发送延迟的问题。
使用类似银行动态口令的验证方式,可以实时进行二次验证,无需再受制于短信无法到达等情况。

2.动态口令的原理?

1
2
3
4
5
6
首先客户端和服务端先协商,或由服务端派发一个秘钥(一般不明文显示),此秘钥不被其他第三方知道。
进行验证时,客户端根据秘钥算出一个密码,服务端根据相同的算法验证。
一般有两种模式:
1.时间模式:由当前时间戳和秘钥,计算出动态口令,一般口令不能变化太快,一般为30s。
服务端对于前后两个时段区间进行验证,只要有一个符合,则视为符合
2.计数器模式:客户端和服务端各有一个计数器,而且事先将数值同步,根据秘钥和计数器进行口令的计算。

3.nodeJs实现?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const speakeasy = require('speakeasy');
const QrCode = require('qrcode');


//生成秘钥二维码
async function createSecret(){
let secret = speakeasy.generateSecret({leagth:20}); //可以指定秘钥长度
/** 格式如下
{
ascii: '/O5y%F^$HP4E8ukH{WT(FnI!Egs<c!&F', //ascii编码
hex:'2f4f357925465e244850344538756b487b575428466e49214567733c63212646',//hex值
base32: 'F5HTK6JFIZPCISCQGRCTQ5LLJB5VOVBIIZXESIKFM5ZTYYZBEZDA',//base32编码,google使用的是这个
otpauth_url: 'otpauth://totp/SecretKey?secret=F5HTK6JFIZPCISCQGRCTQ5LLJB5VOVBIIZXESIKFM5ZTYYZBEZDA',//生成谷歌识别码的地址
}
*/
let code = await QrCode.toDataURL(secret.otpauth_url,{width: 400})
//得到code的base64格式,直接使用<img src="code内容">就可以展示绑定码,用户即可用google authenticator进行扫码绑定
}


// 验证时间模式的动态口令
function verifyTotp(base32Secret, userToken){
return speakeasy.totp.verify({
secret: base32Secret,
encoding: 'base32',
token: userToken,
window: 2, //前后2个时间区间
step: 30, //默认步长30s,也可以自定义
algorithm: 'sha1'
})
}


// 验证计数器模式的动态口令
function verifyHotp(base32Secret, userToken, counter){
return speakeasy.hotp.verify({
secret: base32Secret,
encoding: 'base32',
token: userToken,
counter: counter
})
}


// 可以自定义秘钥的编码格式,默认文本,以及加密方式
function createUserDefinedSecret(){
let secret = speakeasy.generateSecret({ length: 20 });
// 加密方法sha512有的软件不支持
let url = speakeasy.otpauthURL({secret: secret.ascii, label:"Name of Secret", type: 'totp', algorithm: 'sha1'});
let code = await QrCode.toDataURL(url,{width: 400})
}

4.动态口令使用

-------------本文结束感谢您的阅读-------------
分享不易,请我喝杯咖啡吧~~~