TOTP -Google Authenticator两步验证

tech | Comments

使用单一密码的安全性有限,当进行敏感操作时需要更好的验证方法来确保账户安全,比如短信验证,或者像支付宝口令这种基于时间的一次性密码。Google Authenticator是一个实现了OTP的客户端,它不仅可以给Google账户提供保护,也可以把它集成到现有的网站上,以实现两步验证。

TOTP(Time-Based One-Time Password) 是 HOTP(HMAC-Based One-Time Password)的一个特殊形式。

HTOP以一个密钥和一个计数器作为输入,计算出hash值,然后转换成一个整数输出。TOTP中计算器为一个时间值,并且可以把时间分片,例如按30s进行分片, 这样就可以保证30s内计算出来的密码就是一致的,同样,生成的密码也只有30s的有效期。

在实现OTP的时候,HMAC计算出20位的hash值,取其中4为转换成32位的整数,为了方便输入,在把这个整数对106取余,取最后6位作为生成的密码。

以K为服务端和客户端共享的密钥, C为计数器,HTOP的算法可表示为:

1
HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))

HTOP的计算过程:

  1. HMAC-SHA-1(K,C) // 输出20位的二进制字符串
  2. 取其中4位转换成32位的整数
  3. 把上一步的整数对106取余,获取最后6位返回

TOTP中的计数器为一个时间值,T1为当前时间,T0为开始时间,一般取0, X为时间片,一般取30s,则

1
2
C = T = (T1 - T0) / X
TOTP(K, T) = HOTP(K, C) = Truncate(HMAC-SHA-1(K,C))

Google Authenticator可以通过扫描二维码或者手动输入的方式来获取密钥,为了方便输入,Google要求使用base32编码后的密钥,二维码格式可以在它的WIKI上看到 Key-Uri-Format

为了防止设备丢失,用户也可以提前生成几个密码,这个几个密码没有时效性,但是在使用一次后就会失效,可以按Google的建议记在纸上,当设备丢失时作为一次性密码使用。

Fork了一个python实现的使用Google Authenticator进行两部验证的proof of concept。 原来的gist里面有一个参数顺序弄错了。

Comments