摘要:随着互联网密码泄露事件频发,越来越多的产品开始支持多因子认证(MFA),TOTP则是MFA领域里最普遍的一种实现方式,本文介绍TOTP的原理和华为云的实践经验。
原理
TOTP(Time-Based One-Time Password)算法是基于时间的一次性密码算法,根据预共享的密钥与当前时间计算一次性密码。它已被互联网工程任务组接纳为RFC 6238标准,成为主动开放认证的基石,并被用于众多多因子认证系统当中。
TOTP其实并不是一种全新的算法,可以看成是HOTP(HMAC-Based One-Tme Password)算法的一个具体化的场景。HOTP的算法可以在RFC 4226看到详细描述,所以相比HOTP算法,TOTP的RFC文档看起来非常简洁。
上面是HOTP算法的公式,参数K表示共享密钥,参数C表示计数器counter。
TOTP算法实际上是以时间变量作为参数C的HOTP算法,所以TOTP算法的公式应该是
参数K仍然表示共享密钥,而参数T表示时间变量。
时间变量T
TOTP的核心和实践方案也是围绕时间变量T,但T不是简单的时间戳,
X表示步长,默认是30秒,T0表示UTC时间的起始时间戳,即1970年一月一日,Floor函数向下取整。T必须是一个大于32bit的整型,才能支持到2038年以后。例如当X=30时,59对应的T为1,60对应的T为2。
TOTP在MFA上的应用
MFA(Multi-Factor Authentication),多因子认证,是计算机系统中一种进行身份认证的方法,用户需要通过两种或两种以上的认证手段的校验才能进入系统,访问资源。
开通MFA一般都需要先在登录认证系统中将用户的身份和用户的物理设备进行绑定关联,在登录过程中,除了输入密码(用户知道的),还需要输入用户的物理设备(用户持有的)上显示的访问码(passcode)来完成整个身份验证。说明:不是所有的MFA验证过程都需要用户主动输入访问码。
上图示意的过程即MFA的通用流程,例如我们使用网银进行转账就需要拿出在银行窗口开户时银行提供的一个U盾,按下按钮,U盾上即显示一串数字,输入这次数字到网银软件上才能完成转账。
但上图的MFA流程存在一个工程难题,即第4步中认证系统后端还需要向MFA设备(或MFA设备的后台系统)进行一次验证,这个验证过程限制了MFA的应用场景,运行在企业数据中心的认证服务器一般不被允许访问公网,即使访问公网也会因为网络时延导致登录体验变差,TOTP算法的应用很好的解决了这个难题。
使用TOTP算法,只要客户端(证明方)和服务端(校验方)保持时钟一致,且双方预先设置好一个共享密钥的前提下,在同一个时间片段内算出来的值是一样的。正是基于这样的原理,在认证系统中先将用户身份和该共享密钥绑定,再将共享密钥置入物理设备,在认证过程中,物理设备和认证系统各自通过TOTP算法根据共享密钥和时间戳计算出访问码,只要访问码对比一致就能证明用户持有该物理设备,整个认证过程中物理设备和认证系统不需要有交互,非常灵活。
基于TOTP算法的设备,可以分为虚拟(软件)MFA和硬件MFA。
虚拟MFA
虚拟MFA即通过软件来模拟硬件MFA设备,在手机上安装一个支持TOTP协议的APP,例如Google Authenticator, Microsoft Authenticator,华为云APP也同样支持标准的TOTP协议。虚拟MFA通过扫码二维码图片或者手工输入的方式置入校验方生成的共享密钥,并且可以同时关联多个校验方,非常方便实用。
硬件MFA
下图中是一种信用卡形状的硬件MFA,可以放到钱包里,在需要时按下卡片上的按钮即可显示六位数字,非常便携。
安全考虑
1.哈希算法
TOTP算法的强度取决于背后的HOTP算法,但HOTP的哈希函数是HMAC-SHA1,并不是我司推荐的安全算法。TOTP算法在具体实现中也可以使用HMAC-SHA256或HMAC-SHA512,但使用HMAC-SHA1仍然是最通用,兼容性最好的实现,Google Authenticator就是使用HMAC-SHA1。
2.密钥随机性
对TOTP算法最可能的攻击手段就是暴力破解,因此共享密钥必须是密码学安全的密钥,足够随机。密钥长度应该和哈希算法的长度尽量匹配。
另外,校验方必须将密钥存放在安全的区域,使用加密方式保存,防止泄露,只有在需要验证OTP的时候才解密。同时还需要限制最小权限,只有校验方自身才能拿到密钥。
3.通信安全
证明方和校验方应该使用安全的通道通信,例如SSL/TLS。
4.防暴力破解
一般TOTP用于MFA时,校验方只会要求输入6位数字,很容易被暴力破解,在工程实践中可以当第二因子的尝试失败达到一定次数后锁定客户端。
5.保持一次性
TOTP算法在同一个时间片段(例如,30s)内的输出都是一样的,如果同一个TOTP验证已经成功验证过一次,该验证码的第二次尝试应该被拒绝,这样才能保证OTP“一次性”的基本性质。
6.时间片段
时间片段越长,被破解的风险就越高,但考虑到证明方需要人工输入验证码,应该留下足够的操作时间。推荐使用30秒作为默认时间片段,在安全和易用性之间达到一个平衡。
可用性考虑
1.“后向兼容”
因为证明方和校验方都是基于时间来计算OTP,如果证明方在一个时间片段的最后时刻发送OTP,在请求达到校验方时,已经进入下一个时间片段,如果校验方使用当前时间来计算OTP,肯定会匹配失败,这样会导致一定的失败率,影响可用性。
校验方应该不仅仅以接收请求的时间,还应该用上一个时间片段来计算TOTP,增强容错性。不过,容错窗口越长,被攻击风险越高,“后向兼容”一般推荐不超过一个时间片段。
2.支持校准
证明方和校验方的时钟可能不完全一致,特别是很长一段时间没有进行过TOTP认证,时钟偏移导致匹配失败。校验方的认证系统可以提供一种校准(re-sync)的能力,让证明方输入TOTP验证码,校验方往前计算两个时间片段(60s),往后计算一个时间片段(29s),通过匹配结果记录证明方的时钟的偏差值,完成时钟校准。在证明方以后发起验证时,校验方直接使用偏差值计算TOTP。但如果厂商已经支持足够的“后向兼容”,校准不一定需要支持。