发布于2026-07-20 阅读(0)
扫一扫,手机访问
Google Authenticator 用的是 TOTP 算法,每30秒基于密钥和UTC时间戳生成一个动态验证码。密钥得用totp.Generate生成标准Base32字符串,验证时得先解码成字节切片,再用time.Now().UTC().Unix()当时间戳。这几个步骤,哪一步错了,验证就过不了。

直接用 github.com/pquerna/otp/totp 库,别自己手算 HMAC 或拼 Base32。90% 的“扫码后验证失败”问题,都出在这两步上。
totp.Generate,不能手搓随机字符串密钥生成这步,必须用 totp.Generate,别自己手搓随机字符串。为什么?Google Authenticator 和 Authy 只认 RFC 4648 标准 Base32 编码的密钥,而且原始密钥字节长度至少 10 字节、熵值足够高。自己用 crypto/rand.Read 加 base32.StdEncoding.EncodeToString 拼,容易因为字节长度不对、编码表误用(比如用了 URLEncoding)、大小写或填充符处理错,导致扫码失败。
totp.Generate 内部自动用真随机源、选够长字节、标准 Base32 编码、大写无 padding,一步到位。AccountName 和 Issuer,否则生成的 key.URL() 不符合 otpauth:// 规范,扫码工具可能拒绝识别。key, err := totp.Generate(totp.GenerateOpts{
AccountName: "alice@example.com",
Issuer: "MyApp",
Period: 30,
})base32.StdEncoding.DecodeString 密钥字符串验证时犯的错,往往更隐蔽。数据库里存的是 Base32 字符串(比如 "JBSWY3DPEHPK3PXP"),但 totp.ValidateTime 第二个参数要的是原始字节切片([]byte)。跳过解码直接传字符串,HMAC 计算对象就错了,永远不匹配。
totp.ValidateTime(code, []byte(user.Secret), ...) —— 这是把 Base32 字符串当 raw bytes 用了。secretBytes, err := base32.StdEncoding.DecodeString(user.Secret)
if err != nil {
return false
}
valid := totp.ValidateTime(code, secretBytes, time.Now().UTC().Unix(), totp.WithPeriod(30), totp.WithSkew(1))WithSkew(1) 表示允许 ±1 个时间窗口(即 ±30 秒),不加这个,手机时钟差 15 秒就验证失败。time.Now().UTC().Unix(),不是纳秒、毫秒或本地时区时间戳这块,也是个容易踩的坑。 totp.ValidateTime 的第三个参数要求是 int64 类型的 Unix 秒级时间戳(从 1970-01-01 UTC 开始计数)。传错类型或时区,会导致时间步长计算偏移,所有验证全挂。
time.Now().UnixMilli()、time.Now().UnixNano()、time.Now().Local().Unix()time.Now().UTC().Unix() —— UTC 是硬性要求,本地时区哪怕只差 1 小时,也会跨多个 30 秒窗口。sudo systemctl enable systemd-timesyncd && sudo systemctl start systemd-timesyncd最后,绑定流程也需要注意。用户扫码后,前端会提交一个当前动态码。这一步不是形式主义,它是唯一能确认“密钥已正确导入客户端+时间基本对齐”的手段。跳过它直接存密钥,等于允许攻击者上传任意 Base32 字符串完成绑定。
key.URL() 给前端 → 用户扫码 → 提交一次当前 6 位码 → 后端调用 totp.ValidateTime 验证 → 成功才加密存储密钥原文(不是 Base32 字符串!)。[]byte)必须 AES-GCM 加密后落库,绝不能明文存字段如 user.mfa_secret。mf_enabled)必须独立存在,验证逻辑需前置判断:未启用则跳过 TOTP 校验,否则主密码流程会被污染。说到底,最容易被忽略的就是密钥解码和时间戳类型这两个操作。看起来简单,但错一个字符或一个方法名,整个 TOTP 就静默失效,而且没有任何明确报错提示——它只会安静地返回 false。这才是关键所在。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8