张子阳的博客

首页 读书 技术 店铺 关于
张子阳的博客 首页 读书 技术 关于

2FA认证的实现原理

2025-04-15 张子阳 分类: 其他

近期,越来越多的站点使用2FA进行网站的登录验证,例如被广大程序员所熟悉的github。这篇文章就来介绍一下2FA的实现原理。

简介

对于各种应用(例如Web网站)等,传统上的用户验证方式是采用 账号+密码 方式。但这种方式存在两个安全问题:1. 密码意外泄露;2. 黑客程序不断调用登录接口尝试进入,而用户的密码设置过于简单,从而被暴力破解。

对于第2个问题,通常是采用下面两种方式来避免:

  1. 强制密码的设置符合一定的规则,例如:必须大于8位,且包含大小写字母、数字、特殊符号。
  2. 弹出图片验证码,需要输入图片来验证,以确保当前调用接口的是真人(而非计算机脚本)。

除此以外,还有一种方式,就是采用2FA,全称是:双因素认证(Two-Factor Authentication)。

它的核心是,通过2个不同类型的验证因素来确认用户身份:

  1. 你自行设置的密码(传统方式)
  2. 你的动态登录口令(30秒失效 并 重新生成)

两个验证因素均需要符合,才能成功登录系统,这样,即便 自行设置的密码泄露,第三方因为无法获得你的动态口令,依然无法登录系统。

2FA 的工作流程

共享密钥

  1. 当使用2FA时,网站会生成一个 密钥(这个密钥是一串数字,例如:AU65TCZSW3NG55I7ULDEYLOMF3)。网站会将 用户名,例如 张三,和这串密钥 绑定起来。
  2. 用户使用 谷歌验证器(微软验证器、腾讯身份验证小程序),在手机上也添加这个密钥。这个操作通常是 通过扫描 网站提供的二维码 完成的,这个二维码包含了第1步生成的密钥。实际上,这个过程手动输入也是相同的效果,但这样太繁琐。

此时,在网站上,和 用户的手机上(准确来说,是谷歌验证器这样的客户端应用上),共同保存了这个密钥。

生成动态码

  1. 登录的时候,手机会用这个 密钥+当前时间,通过 TOTP算法(基于时间的密码生成算法),计算出一个 6位数,这就是登录用的 “登录口令”。
  2. 这个口令,每过30秒就会变化一次(以30秒为一个单位),所以经常也称作“动态口令”。

验证

  1. 用户先输入自己设置的密码,再输入 手机谷歌验证器上 显示的6位数 “登录口令”(客户端登录口令)。
  2. 网站 基于用户名,找到第一步该用户对应的密钥,然后结合当前时间,使用相同的算法,也生成一个服务端的 “登录口令”。
  3. 如果 两个口令 相同,那么就通过验证;
  4. 如果 用户名称不对、用户手机保存的密钥不对、用户手机的时间不对,都会造成生成的6位“登录口令”不对,从而登录失败。

安全性原理

  1. 密钥只保存在 网站 和 用户手机上,第3方难以获得。
  2. 6位口令有100万种组合,30秒内也无法实现暴力破解。
  3. 登录口令 有效期 只有30秒有效期,即便 登录口令 泄露,很快就过期了。

这样,即便用户的密码泄露,因为无法获得 “登录口令”,第三方也无法登录; 同时,也不是很需要图片验证码,来校验是否真人,因为缺少密钥的情况下, 登录口令 无论如何也算不对,同样无法进入系统。

感谢阅读,希望这篇文章能给你带来帮助!