你每天用的谷歌身份验证器、网易将军令,到底是怎么算出6位验证码的?
为什么离线能用?为什么时间不准就失效?服务器不能碰硬件,怎么校准时间?

这篇文章从原理 → 步骤 → 公式 → 代码 → 二维码生成,一次性讲透。


一、核心原理(一句话)

谷歌MFA、网易将军令,原理完全一样,都是:
TOTP 基于时间的一次性密码
公式:
共享密钥 + 固定时间窗口 → HMAC-SHA1哈希 → 截取6位数字 = 动态口令


二、完整生成步骤(最清晰版)

步骤1:生成时间计数器 T

把时间切成固定一段(谷歌30秒,将军令60秒)

T = 当前Unix时间戳 // 窗口大小

同一窗口内,T 永远不变 → 验证码不变

步骤2:HMAC-SHA1 加密

服务器、验证器各存一份相同密钥,各自计算:

HMAC-SHA1( 密钥, T )

输出固定 20 字节哈希。

步骤3:偏移截取(TOTP标准规则)

  1. 取哈希最后1字节
  2. 低4位 = 偏移量 offset
  3. 从 offset 开始取4个字节
  4. 屏蔽最高位,变成正数

步骤4:取最后6位

验证码 = 结果 % 1000000

得到你看到的 6 位数字。


三、谷歌MFA vs 网易将军令对比

项目 谷歌MFA 网易将军令
算法 TOTP RFC6238 TOTP 自研
窗口 30秒 60秒
形态 APP 硬件/APP
同步 手机自动授时 硬件晶振
容错 误差>30秒失效 误差>60秒失效

结论:网易将军令 = 硬件版、60秒窗口的谷歌MFA


四、时间校准原理(服务器不能访问硬件)

❌ 不能读硬件时钟
❌ 不能改硬件时间

✅ 正确方式:算法补偿

  1. 你输入当前验证码
  2. 服务器计算前后多个窗口的口令
  3. 找到匹配 → 算出时差
  4. 服务器记录时差,以后自动对齐

五、最强代码:生成谷歌验证器二维码 + 实时计算验证码

功能

  1. 自动生成密钥
  2. 生成谷歌验证器可扫描的二维码
  3. 实时输出6位验证码(和手机完全一致)
  4. 纯离线运行

代码(可直接运行)

import hmac, time, base64, hashlib
import qrcode  # 需要安装:pip install qrcode

# ======================
# 1. 生成TOTP 6位验证码
# ======================
def get_totp(secret_base32, interval=30):
    # 密钥解码(谷歌用Base32)
    key = base64.b32decode(secret_base32, casefold=True)
    
    # 时间计数器 T
    T = int(time.time() // interval)
    
    # 转8字节大端
    T_bytes = T.to_bytes(8, byteorder='big')
    
    # HMAC-SHA1
    hmac_result = hmac.new(key, T_bytes, hashlib.sha1).digest()
    
    # 偏移截取
    offset = hmac_result[-1] & 0x0F
    code = int.from_bytes(hmac_result[offset:offset+4], byteorder='big') & 0x7FFFFFFF
    
    # 6位数字
    return f"{code % 1000000:06d}"

# ======================
# 2. 生成谷歌验证器二维码
# ======================
def generate_google_qr(secret, account_name, issuer="我的MFA演示"):
    # 谷歌验证器标准URI格式
    uri = f"otpauth://totp/{issuer}:{account_name}?secret={secret}&issuer={issuer}"
    img = qrcode.make(uri)
    img.show()  # 自动弹出二维码
    print("✅ 二维码已弹出,用谷歌验证器直接扫描")
    print("🔑 密钥(备份):", secret)
    print("🔗 URI:", uri)

# ======================
# 3. 运行演示
# ======================
if __name__ == "__main__":
    # 生成随机密钥(也可自己写16位大写字母)
    secret = "JBSWY3DPEHPK3PXP"  # 固定测试密钥
    
    # 生成二维码(谷歌验证器可扫)
    generate_google_qr(secret, "test@example.com")
    
    # 实时输出验证码(和手机完全一样)
    print("\n实时MFA验证码:")
    while True:
        code = get_totp(secret)
        print(f"\r→ {code}", end="")
        time.sleep(1)

六、安装依赖

pip install qrcode

七、代码说明(对应原理步骤)

  1. base64.b32decode → 解码谷歌验证器标准密钥
  2. time.time()//30 → 30秒时间窗口
  3. hmac.new(sha1) → 核心加密
  4. offset = 哈希最后1字节 & 0x0F → 偏移量
  5. & 0x7FFFFFFF → 屏蔽负数
  6. % 1000000 → 6位验证码
  7. otpauth://totp/ → 谷歌验证器官方二维码格式

八、效果

✅ 运行自动弹出二维码
✅ 谷歌验证器扫描即可添加
✅ 电脑输出的验证码 = 手机验证码
✅ 每30秒自动刷新
✅ 100% 离线运行


九、终极总结

  1. 谷歌MFA = 网易将军令,原理完全相同(TOTP)
  2. 核心:密钥 + 时间窗口 + HMAC-SHA1
  3. 同一时间窗口 → 验证码一样
  4. 服务器不碰硬件,靠算法反推时差校准
  5. 15行代码 = 完整谷歌MFA实现

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐