2FA认证的实现原理
2025-04-15
张子阳
分类: 其他
近期,越来越多的站点使用2FA进行网站的登录验证,例如被广大程序员所熟悉的github。这篇文章就来介绍一下2FA的实现原理。
简介
对于各种应用(例如Web网站)等,传统上的用户验证方式是采用 账号+密码 方式。但这种方式存在两个安全问题:1. 密码意外泄露;2. 黑客程序不断调用登录接口尝试进入,而用户的密码设置过于简单,从而被暴力破解。
对于第2个问题,通常是采用下面两种方式来避免:
- 强制密码的设置符合一定的规则,例如:必须大于8位,且包含大小写字母、数字、特殊符号。
- 弹出图片验证码,需要输入图片来验证,以确保当前调用接口的是真人(而非计算机脚本)。
除此以外,还有一种方式,就是采用2FA,全称是:双因素认证(Two-Factor Authentication)。
它的核心是,通过2个不同类型的验证因素来确认用户身份:
- 你自行设置的密码(传统方式)
- 你的动态登录口令(30秒失效 并 重新生成)
两个验证因素均需要符合,才能成功登录系统,这样,即便 自行设置的密码泄露,第三方因为无法获得你的动态口令,依然无法登录系统。
2FA 的工作流程
共享密钥
- 当使用2FA时,网站会生成一个 密钥(这个密钥是一串数字,例如:AU65TCZSW3NG55I7ULDEYLOMF3)。网站会将 用户名,例如 张三,和这串密钥 绑定起来。
- 用户使用 谷歌验证器(微软验证器、腾讯身份验证小程序),在手机上也添加这个密钥。这个操作通常是 通过扫描 网站提供的二维码 完成的,这个二维码包含了第1步生成的密钥。实际上,这个过程手动输入也是相同的效果,但这样太繁琐。
此时,在网站上,和 用户的手机上(准确来说,是谷歌验证器这样的客户端应用上),共同保存了这个密钥。
生成动态码
- 登录的时候,手机会用这个 密钥+当前时间,通过 TOTP算法(基于时间的密码生成算法),计算出一个 6位数,这就是登录用的 “登录口令”。
- 这个口令,每过30秒就会变化一次(以30秒为一个单位),所以经常也称作“动态口令”。
验证
- 用户先输入自己设置的密码,再输入 手机谷歌验证器上 显示的6位数 “登录口令”(客户端登录口令)。
- 网站 基于用户名,找到第一步该用户对应的密钥,然后结合当前时间,使用相同的算法,也生成一个服务端的 “登录口令”。
- 如果 两个口令 相同,那么就通过验证;
- 如果 用户名称不对、用户手机保存的密钥不对、用户手机的时间不对,都会造成生成的6位“登录口令”不对,从而登录失败。
安全性原理
- 密钥只保存在 网站 和 用户手机上,第3方难以获得。
- 6位口令有100万种组合,30秒内也无法实现暴力破解。
- 登录口令 有效期 只有30秒有效期,即便 登录口令 泄露,很快就过期了。
这样,即便用户的密码泄露,因为无法获得 “登录口令”,第三方也无法登录; 同时,也不是很需要图片验证码,来校验是否真人,因为缺少密钥的情况下, 登录口令 无论如何也算不对,同样无法进入系统。
感谢阅读,希望这篇文章能给你带来帮助!