DS 地址:
https://chat.deepseek.com/a/chat/s/f1abdf92-5c4a-42d0-a0c8-c8382b3f7a71
MFA(多因素认证)的核心原理是:通过组合多个独立的身份验证因素,显著提高账户安全性。 它基于一个简单而强大的理念:即使一个因素(如密码)被泄露或破解,攻击者仍然难以同时获取或仿冒其他因素。
📱 常见 MFA 方法示例
密码 + 认证器 App 动态码: 最常用且推荐的方式。输入密码后,打开手机上的 App(如 Google/Microsoft Authenticator),输入当前显示的 6 位数字码。
密码 + 安全密钥: 输入密码后,插入物理安全密钥(如 YubiKey)并按一下按钮完成验证。安全性极高,且防钓鱼。
密码 + 生物识别: 输入密码后,用指纹或面部解锁手机或电脑来完成验证(这通常利用了设备本地的生物识别作为第二因素)。
密码 + 短信验证码: 输入密码后,系统发送一个一次性验证码到用户手机短信,用户输入该码。(注意:因 SIM 卡交换攻击等风险,这是最不安全的 MFA 方式,应尽量避免)
密码 + 认证器 App 动态码: 最常用且推荐的方式。输入密码后,打开手机上的 App(如 Google/Microsoft Authenticator),输入当前显示的 6 位数字码。
这个东西的原理是什么?
认证器 App(如 Google Authenticator、Microsoft Authenticator 等)生成的 6 位动态验证码 的核心原理是 基于时间的一次性密码算法。其技术标准称为 TOTP。
以下是其工作原理的详细解析:
🔑 1. 共享密钥的建立(初始设置)
用户启用 MFA: 在网站/应用(服务端)上选择“启用认证器 App”。
生成共享密钥: 服务端生成一个随机、唯一、高熵(高度随机且复杂)的密钥。这是一个保密字符串。
密钥安全传输:
服务端将密钥转换为一个 QR 码 显示给用户。
用户使用手机上的认证器 App 扫描这个 QR 码。
QR 码中通常包含:otpauth://totp/账户名?secret=共享密钥&issuer=服务名称 等信息。
App 保存密钥: 认证器 App 安全地(通常存储在手机的安全区域,如 Keychain/Keystore)保存这个共享密钥 Secret。这个密钥是后续所有动态码生成的基础,且永远不会通过网络传输给服务端。
⏱ 2. 动态码的生成(基于时间 - TOTP)
获取当前时间戳: 认证器 App 获取手机的当前 UTC 时间。
计算时间步长: 将当前时间戳(秒数)除以一个预设的时间窗口(通常是 30 秒),然后向下取整,得到一个整数 C(称为计数器值)。
公式:C = floor(当前 Unix 时间戳 / 时间窗口)
例如:当前时间戳是 1650000000 秒,时间窗口是 30 秒,则 C = 1650000000 / 30 = 55000000。
HMAC-SHA1 计算: 使用 HMAC-SHA1(基于哈希的消息认证码)算法,以共享密钥 Secret 作为密钥,时间步长计数器值 C 作为消息,计算出一个哈希值 HMAC(Secret, C)。
HMAC-SHA1 是一种密码学哈希函数,能确保即使知道输入 C 和输出哈希值,也极难反推出密钥 Secret。
动态截断 (DT): 从步骤 3 得到的 20 字节 HMAC 结果中,通过一个算法(动态截断)提取出一个 4 字节(31 位)的动态二进制数 S。
转换为数字: 将 S 对 1,000,000 取模(S mod 10^6),得到一个范围在 000000 到 999999 之间的整数。
显示 6 位码: 将这个整数格式化为 6 位数字(不足 6 位前面补零),显示在 App 界面上。这个码每 30 秒(或设定的时间窗口)自动刷新一次。
3. 服务端的验证过程
用户输入动态码: 用户登录时,在输入正确的用户名密码后,将认证器 App 上当前显示的 6 位动态码输入到登录界面。
服务端执行相同计算: 服务端执行与 App 端完全相同的步骤:
获取当前 UTC 时间(确保服务端时间准确非常重要,通常使用 NTP 同步)。
计算相同的时间步长计数器值 C'(C' = floor(当前时间戳 / 30))。
使用该用户对应的共享密钥 Secret(在初始设置时已安全存储)。
计算 HMAC(Secret, C')。
执行动态截断 (DT) 得到 S'。
计算 S' mod 1000000 得到预期的 6 位数字。
时间容差验证: 由于用户输入需要时间,且手机和服务端时钟可能存在微小偏差,服务端通常不会只检查当前时间步 C' 计算出的码。它会检查:
C'(当前时间步)计算出的码
C' - 1(前一个时间步,比如 30 秒前)计算出的码
C' + 1(后一个时间步,比如 30 秒后)计算出的码
(有些系统甚至允许 ±2 个时间步,即最多前后 1 分钟)。
匹配验证: 服务端将用户输入的 6 位码与步骤 3 中计算出的 1 到 3 个(或 5 个)预期码进行比较。
结果判定:
如果用户输入的码等于其中任何一个预期码 → 验证成功,允许登录。
如果用户输入的码不等于任何一个预期码 → 验证失败,拒绝登录。
一次性原则: 即使攻击者截获了某个时间窗口的动态码,该码在下一个时间窗口(如 30 秒后)就会失效,并且服务端通常也会记录或标记使用过的码(在有效期内),防止同一码重复使用。
关键安全特性与优势
动态性: 验证码基于时间不断变化,一次性有效,极大降低了被截获重放的风险。
离线生成: 认证器 App 无需联网 即可生成动态码,因为它只需要共享密钥 Secret 和本地时间。这提高了可用性和安全性(避免网络传输风险)。
密钥保密: 核心的共享密钥 Secret 只在初始设置时通过安全通道(QR 码扫描)传输一次,之后永久存储在手机和服务端的安全存储中,不再传输。App 端无法读取服务端的密钥,服务端也无法读取 App 端的密钥。
基于密码学: 使用 HMAC-SHA1 算法,确保了即使知道多个动态码,也无法推导出共享密钥 Secret(计算不可逆)。
独立设备: 第二个因素(动态码)依赖于用户物理持有的手机设备(“Something You Have”)。
相比短信更安全: 避免了短信可能面临的 SIM 卡劫持、网络监听、手机号暴露等风险。
📝 总结
认证器 App 动态码(TOTP)的原理是:服务端和用户手机 App 在初始设置时共享一个高度保密的密钥 Secret。之后,双方都使用这个密钥和高度同步的精确时间(基于 UTC),通过相同的 HMAC-SHA1 算法和动态截断取模过程,独立计算出相同的、每 30 秒变化一次的 6 位数字验证码。 服务端在验证时会考虑时间容差,检查前后几个时间窗口的码是否匹配用户输入的码。其安全性核心在于密钥的保密性、算法的单向性以及验证码的动态性和一次性。
因此,“密码 + 认证器 App 动态码” 的组合,完美体现了 MFA 的核心:你知道的(密码) + 你拥有的(存有密钥的手机) + 动态变化难以预测/重放(TOTP 算法),从而提供强大的安全保障。