内容简介:双重认证(英语:Two-factor authentication,缩写为2FA), 又译为双重验证、双因子认证、双因素认证、二元认证,又称两步骤验证(2-Step Verification,又译两步验证), 是一种认证方法,使用两种不同的元素,合并在一起,来确认用户的身份,是多因素验证中的一个特例.TOTP 的全称是”基于时间的一次性密码”(Time-based One-time Password). 它是公认的可靠解决方案,已经写入国际标准 RFC6238.
原文地址https://mojotv.cn/go/golang-2fa
1. 前言
双重认证(英语:Two-factor authentication,缩写为2FA), 又译为双重验证、双因子认证、双因素认证、二元认证,又称两步骤验证(2-Step Verification,又译两步验证), 是一种认证方法,使用两种不同的元素,合并在一起,来确认用户的身份,是多因素验证中的一个特例.
- 使用银行卡时,需要另外输入PIN码,确认之后才能使用其转账功能.
- 登陆电脑版微信时,用已经登录同一账号的手机版微信扫描特定二维码进行验证.
- 登陆校园网系统时,通过手机短信或学校指定的手机软件进行验证.
- 登陆Steam和Uplay等游戏平台时,使用手机令牌或Google身份验证器进行验证.
2. TOTP的概念
TOTP 的全称是”基于时间的一次性密码”(Time-based One-time Password). 它是公认的可靠解决方案,已经写入国际标准 RFC6238.
它的步骤如下.
- 第一步,用户开启双因素认证后,服务器生成一个密钥.
- 第二步:服务器提示用户扫描二维码(或者使用其他方式),把密钥保存到用户的手机.也就是说,服务器和用户的手机,现在都有了同一把密钥.
- 第三步,用户登录时,手机客户端使用这个密钥和当前时间戳,生成一个哈希,有效期默认为30秒.用户在有效期内,把这个哈希提交给服务器.(注意,密钥必须跟手机绑定.一旦用户更换手机,就必须生成全新的密钥.)
- 第四步,服务器也使用密钥和当前时间戳,生成一个哈希,跟用户提交的哈希比对.只要两者不一致,就拒绝登录.
3. RFC6238
根据RFC 6238标准,供参考的实现如下:
- 生成一个任意字节的字符串密钥K,与客户端安全地共享.
- 基于T0的协商后,Unix时间从时间间隔(TI)开始计数时间步骤,TI则用于计算计数器C(默认情况下TI的数值是T0和30秒)的数值
- 协商加密哈希算法(默认为SHA-1)
- 协商密码长度(默认6位)
4. 2FA双因素认证 Golang 代码实现 TOTP
生成一次性密码的伪代码
function GoogleAuthenticatorCode(string secret) key := base32decode(secret) message := floor(current Unix time / 30) hash := HMAC-SHA1(key, message) offset := last nibble of hash truncatedHash := hash[offset..offset+3] //4 bytes starting at the offset Set the first bit of truncatedHash to zero //remove the most significant bit code := truncatedHash mod 1000000 pad code with 0 until length of code is 6 return code
生成事件性或计数性的一次性密码伪代码
function GoogleAuthenticatorCode(string secret) key := base32decode(secret) message := counter encoded on 8 bytes hash := HMAC-SHA1(key, message) offset := last nibble of hash truncatedHash := hash[offset..offset+3] //4 bytes starting at the offset Set the first bit of truncatedHash to zero //remove the most significant bit code := truncatedHash mod 1000000 pad code with 0 until length of code is 6 return code
- 关于代码中为什么会出现难懂的位运算 -> 追求运算效率
package main import ( "crypto/hmac" "crypto/sha1" "encoding/binary" "fmt" "time" ) func main() { key := []byte("MOJOTV_CN_IS_AWESOME_AND_AWESOME_SECRET_KEY") number := totp(key, time.Now(), 6) fmt.Println("2FA code: ",number) } func hotp(key []byte, counter uint64, digits int) int { //RFC 6238 h := hmac.New(sha1.New, key) binary.Write(h, binary.BigEndian, counter) sum := h.Sum(nil) //取sha1的最后4byte //0x7FFFFFFF 是long int的最大值 //math.MaxUint32 == 2^32-1 //& 0x7FFFFFFF == 2^31 Set the first bit of truncatedHash to zero //remove the most significant bit // len(sum)-1]&0x0F 最后 像登陆 (bytes.len-4) //取sha1 bytes的最后4byte 转换成 uint32 v := binary.BigEndian.Uint32(sum[sum[len(sum)-1]&0x0F:]) & 0x7FFFFFFF d := uint32(1) //取十进制的余数 for i := 0; i < digits && i < 8; i++ { d *= 10 } return int(v % d) } func totp(key []byte, t time.Time, digits int) int { return hotp(key, uint64(t.Unix())/30, digits) //return hotp(key, uint64(t.UnixNano())/30e9, digits) }
5. 参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 身份认证之双因素认证 2FA
- 技术讨论 | 使用CredSniper获取双因素认证令牌
- 开源SSH双因素登陆认证系统JXOTP了解一下续
- 微软 Bug 悬赏:绕过多因素认证最高可获10万美元奖励
- PyPI 已支持双因素认证,提升下载 Python 软件包安全性
- 挖洞经验 | HackerOne的双因素认证和上报者黑名单绕过漏洞($10,000)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP Hacks
Jack Herrington D. / O'Reilly Media / 2005-12-19 / USD 29.95
Programmers love its flexibility and speed; designers love its accessibility and convenience. When it comes to creating web sites, the PHP scripting language is truly a red-hot property. In fact, PH......一起来看看 《PHP Hacks》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
UNIX 时间戳转换
UNIX 时间戳转换