🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 概述 双因素认证(Two-factor authentication,简称 2FA) ### 双因素认证的概念 - 秘密信息:只有该用户知道、其他人不知道的某种信息,比如密码 - 个人物品:该用户的私人物品,比如身份证、钥匙 - 生理特征:该用户的遗传特征,比如指纹、相貌、虹膜等等 ### 双因素认证方案 - 常用的双因素组合是密码 + 某种个人物品 - 密码 + 手机就成了最佳的双因素认证方案 - 安全的双因素认证不是密码 + 短消息,而是TOTP ### TOTP 的概念 - TOTP 的全称是"基于时间的一次性密码"(Time-based One-time Password) - 它是公认的可靠解决方案,已经写入国际标准 <br/> 步骤: 1. 第一步,用户开启双因素认证后,服务器生成一个密钥 2. 第二步:服务器提示用户扫描二维码(或者使用其他方式),把密钥保存到用户的手机。也就是说,服务器和用户的手机,现在都有了同一把密钥 ![](http://www.ruanyifeng.com/blogimg/asset/2017/bg2017110107.png) 注意,密钥必须跟手机绑定。一旦用户更换手机,就必须生成全新的密钥 3. 第三步,用户登录时,手机客户端使用这个密钥和当前时间戳,生成一个哈希,有效期默认为30秒。用户在有效期内,把这个哈希提交给服务器 4. 第四步,服务器也使用密钥和当前时间戳,生成一个哈希,跟用户提交的哈希比对。只要两者不一致,就拒绝登录。 ![](http://www.ruanyifeng.com/blogimg/asset/2017/bg2017110108.jpg) ### TOTP 的算法 该算法可以保证手机客户端和服务器保证30秒期间都得到同一个哈希 ``` TC = floor(unixtime(now) / 30) // HASH就是约定的哈希函数,默认是 SHA-1 TOTP = HASH(SecretKey, TC) ``` ### TOTP 的实现 ``` npm install --save 2fa ``` ``` // 1. 生成一个32位字符的密钥 var tfa = require('2fa'); tfa.generateKey(32, function(err, key) { console.log(key); }); // b5jjo0cz87d66mhwa9azplhxiao18zlx // 2. 生成hash var tc = Math.floor(Date.now() / 1000 / 30); var totp = tfa.generateCode(key, tc); console.log(totp); // 683464 ```