摘要:随着互联网密码泄露事件频发,越来越多的产品开始支持多因子认证(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。但如果厂商已经支持足够的“后向兼容”,校准不一定需要支持。

点击关注,第一时间了解华为云新鲜技术~

解读登录双因子认证(MFA)特性背后的TOTP原理的更多相关文章

  1. 强制禁用gitlab的双因子认证:Two-Factor Authentication

    (一)问题描述: 此博客解决如下问题:禁用gitlab的双因子认证 禁用前,如图(此时,你在gitlab中什么也干不了) (二)思路分析: 百度了很多方法,都不可靠(如不可靠的说明:https://s ...

  2. Linux 利用Google Authenticator实现ssh登录双因素认证

    1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...

  3. centos6.5使用Google auth进行双因子认证

    1.环境 系统:centos6.5 x86_64 [root@uu ~]# uname -a Linux uu 2.6.32-642.el6.x86_64 #1 SMP Wed Apr 13 00:5 ...

  4. 【Linux】使用Google Authenticator 实现ssh登录双因素认证

    一般来说,使用ssh远程登录服务器,只需要输入账号和密码,显然这种方式不是很安全.为了安全着想,可以使用GoogleAuthenticator(谷歌身份验证器),以便在账号和密码之间再增加一个验证码, ...

  5. odoo12之应用:一、双因子验证(Two-factor authentication, 2FA)(HOTP,TOTP)附源码

    前言 双因子认证:双因子认证(2FA)是指结合密码以及实物(信用卡.SMS手机.令牌或指纹等生物标志)两种条件对用户进行认证的方法.--百度百科 跟我一样"老"的网瘾少年想必一定见 ...

  6. (诊断)解决GitHub使用双因子身份认证“Two-Factor Athentication”后无法git push 代码的“fatal: Authentication failed for ...”错误

    在GitHub上采取双因子身份认证后,在git push 的时候将会要求填写用户的用户名和密码,用户名就是用户在GitHub上申请的用户名,但是密码不是普通登录GitHub的密码. 一旦采取双因子身份 ...

  7. 用Abp实现双因素认证(Two-Factor Authentication, 2FA)登录(一):认证模块

    @ 目录 原理 用户验证码校验模块 双因素认证模块 改写登录 在之前的博文 用Abp实现短信验证码免密登录(一):短信校验模块 一文中,我们实现了用户验证码校验模块,今天来拓展这个模块,使Abp用户系 ...

  8. 轻松搭建CAS 5.x系列(8)-在CAS Server增加双因素认证(DUO版)

    概述说明 为了让系统更加安全,很多登录会加入双因素认证.何为双因素,如果把登陆作为开一扇门的话,那就是在原来的锁上再加一把锁,第二锁用新的钥匙,这样安全系数就更加高了. CAS是通过账号名和密码来认证 ...

  9. 业余草双因素认证(2FA)教程

    所谓认证(authentication)就是确认用户的身份,是网站登录必不可少的步骤.密码是最常见的认证方法,但是不安全,容易泄露和冒充.越来越多的地方,要求启用双因素认证(Two-factor au ...

  10. 双因素认证(2FA)教程

    所谓认证(authentication)就是确认用户的身份,是网站登录必不可少的步骤. 密码是最常见的认证方法,但是不安全,容易泄露和冒充. 越来越多的地方,要求启用 双因素认证(Two-factor ...

随机推荐

  1. Perceptual Losses 风格迁移论文复现小记

    看了一篇李飞飞组的论文 Perceptual Losses for Real-Time Style Transfer and Super-Resolution. 论文地址为:https://arxiv ...

  2. 3.MongoDB-备份恢复

    备份工具 (1)** mongoexport/mongoimport (2)***** mongodump/mongorestore 备份工具区别在那里? 应用场景总结: mongoexport/mo ...

  3. JPA中@ElementCollection使用

    转载请注明出处: 在JPA中,@ElementCollection注解主要用于映射集合属性,例如List.Set或数组等集合属性,以及Map结构的集合属性,每个属性值都有对应的key映射.这个注解可以 ...

  4. Kubernetes 漫游:理解 ConfigMap

    安装说明 通过 docker desktop 可以安装适用于单机和开发环境单机版的 K8S,如果 docker desktop 无法启动 Kubernates 通过以下方式解决: 一:添加国内镜像源 ...

  5. 终端必备大杀器----Fish

    目录 下载 安装 添加 权限 依赖库安装 cmake 预处理 编译 安装 配置fish 其他 下载 Github 地址-- fish-shell openSUSE 开源下载地址 openSUSE 开源 ...

  6. 文心一言 VS 讯飞星火 VS chatgpt (142)-- 算法导论12.1 2题

    二.用go语言,二叉搜索树性质与最小堆性质(见 6.1 节)之间有什么不同?能使用最小堆性质在 O(n)时间内按序输出一棵有 n 个结点树的关键字吗?可以的话,请说明如何做,否则解释理由. 文心一言: ...

  7. Java 21 官方速览:全面拥抱虚拟线程

    前言 首先,感谢一下不少xdm私信关心我的身体状况,我也不是什么厉害的大佬,点开通知看到一堆私信还是蛮感动的. 近来有意大幅缩短了更新频率,增加了日常调养身体的时间,淋巴结确实变小了,睡眠也逐渐正常, ...

  8. Java数组最常用操作方法(Arrays类)

    最近在写代码的过程中发现我们很多地方都会处理数组,有时只是模糊的记得有API可以调用,每次都查文档很是费事儿,适当的总结希望提高开发速度 一.申明数组 数组的申明十分简单也十分的基础,注意第三种申明方 ...

  9. Activity发送信息给Fragment

    在MainActivity中设置发送的信息,在fragment中接收, @Override public void onClick(View view) { switch (view.getId()) ...

  10. 【YOLOv5】实现扑克牌的点数识别

    前言 其实年初的时候,我也跟着别人的源码,用 Tensoflow 实现过扑克牌的目标检测.虽然也通过博文的方式记录了,但是那个项目使用的 TF 版本比较旧,自身对 TF 并不熟.后期如果说要升级或修改 ...