企业账号安全体系建设之双因素认证系统设计

双因素身份认证(2FA)

概念

所谓的双因素,就是在系统登录的时候除了证明你是谁之外(输入你的账号密码),还需要证明你拥有什么(输入验证码)。双因素认证能极大地提高用户的账号安全水平,因为在今天数据泄漏事件层出不穷的情况下,攻击者窃取用户的账号密码是比较容易的,但是攻击者要同时窃取用户的登录设备(一般是手机)就非常困难了。

这个验证码被称为 OTP(One-Time Password,一次性密码),是通过在客户端和服务端共享密钥来实现的,有两个实现方法:

  1. HOTP (HMAC-Based One-Time Password Algorithm),是基于 HMAC 算法生成的一次性密码,也称事件同步的动态密码。实现规范是 RFC 4226 ,对应的计算公式:
HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))
K:客户端和服务器事先协商好的一个密钥K
C:客户端和服务器各有一个事件计数器C,并且事先将计数值同步
Truncate:将HMAC-SHA-1产生的20字节的字符串转换为若干位十进制数字的算法
  1. TOTP (Time-Based One-Time Password Algorithm),是 OTP 的算法变种,使用当前时间替换掉 HOTP 的事件计数器 C,也称时间同步的动态密码。实现规范是 RFC 6238注意:该RFC包含了服务端的源码,需要仔细研究),对应的计算公式:
TOTP = Truncate(HMAC-SHA-1(K,T))

T = (当前的Unix格式时间戳 - T0) / X
T0 是初试时间,默认为 0
X 是时间步长,默认30秒
官方文档中的例子:假设当前unix时间=59,T0=0,X=30,则T=1;假设当前unix时间=60,T0=0,X=30,则T=2
也就是对T的值向下取整

只要保证客户端与服务端的时间一致,TOTP 就能根据同一个密钥种子分别在两端计算出同一个验证码,所以生成验证码的时候是完全不依赖网络的。针对 TOTP 的攻击只有针对共享密钥的暴力穷举法,因此防护重点在于共享密钥[1]

  • 密钥生成算法必须采用真随机数或者是用加密强度高的伪随机数生成算法
  • 客户端与服务端沟通密钥时必须使用安全的传输方法,譬如 IPsec 隧道或是基于 SSL/TLS 的通信协议
  • 密钥需要加密落盘,只在验证随机码的时候短暂解密,然后再重新加密罗盘,缩短在内存中暴露的时间
  • 密钥需要存储在安全的地方并限制只有验证系统可以访问

产品

TOTP 的生成算法/源码是公开的,所以并不存在服务端产品,下面的两个产品指的是用于扫描二维码的移动端应用,都支持 android 和 ios。

系统场景设计

场景一:用户在登录系统时,浏览器弹出二维码,用户扫码后再输入验证码:[2]

场景二:用户在登录系统时,直接打开企业微信或其他内部开发的移动端应用,该应用上自动生成验证码,用户输入该验证码即可

引用

[1] TOTP: Time-Based One-Time Password Algorithm
[2] nodejs 接入 google 身份验证器(authenticator)

文章作者: kylinlin
文章链接: https://kylinlingh.github.io/2023/01/17/%E4%BC%81%E4%B8%9A%E8%B4%A6%E5%8F%B7%E5%AE%89%E5%85%A8%E4%BD%93%E7%B3%BB%E5%BB%BA%E8%AE%BE%E4%B9%8B%E5%8F%8C%E5%9B%A0%E7%B4%A0%E8%AE%A4%E8%AF%81%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Water&Melon's Blog