谷歌的两步验证器现在的应用太广泛了, 但凡稍微认真点的站点在登陆时都会要求输入两步验证码, 但是这也带来一个问题, 就是登录网站时要多操作一步, 而且更难受的是--我需要掏手机.
所以为什么不写一个命令行的两步验证器工具呢?
谷歌的两步验证器基于两个算法: HOTP 和 TOTP. 我们先来介绍 HTOP, 因为后者仅仅是前者的简单扩展. HOTP 被 RFC4226 描述, 为了简单起见, 我只记录其中的关键算法部分.
截断步骤如下:
offset = hmac_result[19] & 0xf
hmac_result[offset:offset+4]
还原出一个大端序的 uint32 dbc(dynamic binary code)
dbc = dbc & 0x7fffffff
. 屏蔽 dbc 的最高有效位的原因是为了避免关于有符号和无符号模计算的混淆. 不同的处理器以不同的方式执行取模操作, 这一步可以消除关于符号整数取模计算的歧义.dbc = dbc % 1000000
.Go 代码实现
func main() {
secret := "ECM5HE2DKHAFJT4ZEFA9PK4A3Q"
c := uint64(0)
// 对 K 进行 Base32 解码, 需要在密码尾部添加 = 使得其长度为 8 的倍数
secret += strings.Repeat("=", -len(secret)&7)
k, _ := base32.StdEncoding.DecodeString(secret)
h := hmac.New(sha1.New, k)
binary.Write(h, binary.BigEndian, c)
sum := h.Sum(nil)
v := binary.BigEndian.Uint32(sum[sum[19]&0x0F:]) & 0x7FFFFFFF
fmt.Println(v % 1000000)
}
TOTP 是 HOTP 的简单简单扩展, 其定义在 RFC6238. 简单来说, TOTP 使用当前的时间步长来替换自增的 C. TOTP 解决了以下几个问题:
算法步骤如下:
C = T / X
Go 代码实现
// 将上述代码的第二行修改为以下代码即可
c := time.Now().Unix() / 30
看到首页有关于 2fa 的帖子, 就把自己博文粘贴过来了, 原文: http://accu.cc/content/misc/2fa/