You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用j256时服务器重启后Google Authenticator验证码校验失败问题

问题根因

你遇到的Unable to invoke Cipher due to bad padding报错和缓存清空没有关系,核心原因是:
你以为做了安全持久化的TOTP密钥,并不是Google Authenticator识别的明文原始种子,而是被服务端加密后的密文;而你用的内置2FA模块默认没有配置固定的加解密密钥,每次服务启动时会在内存中随机生成一个临时对称密钥,用来加密存储所有新生成的TOTP种子。
服务重启前,内存里的临时加密密钥和加密旧种子用的是同一个,解密正常所以校验100%通过;服务重启后,内存里生成了全新的临时加密密钥,拿这个新密钥去解之前旧密钥加密的种子密文,就会触发填充错误,直接导致校验失败。
这也能解释为什么重启后新生成的密钥可以正常工作:新生成的种子是用当前进程的新临时密钥加密存储的,加解密用的是同一个密钥,自然不会报错。

补充:TOTP(Google Authenticator用的就是标准TOTP算法)本身是无状态校验逻辑,校验过程只需要三个要素:原始共享种子、当前时间戳、用户输入的6位验证码,根本不需要依赖服务端缓存存储关联数据,不存在缓存清空导致校验失败的可能。

修复步骤

  • 找到你所用框架/组件2FA模块的加密密钥配置项,不要使用默认的启动时随机生成密钥的逻辑,手动配置一个长度符合要求的固定对称加密密钥(比如AES-256算法需要32位随机字符串,建议存到环境变量或独立的配置中心,不要硬编码在业务代码里),保证所有服务实例、每次服务启动都用同一个固定密钥做TOTP种子的加解密。
  • 对于服务重启前已经生成、被旧临时密钥加密的存量TOTP种子:如果能找回服务上次启动时用的临时密钥,可以先把所有存量密文解密成原始明文种子,再用新配置的固定密钥重新加密后存回数据库,用户不需要重新绑定;如果找不回旧临时密钥,只能通知存量用户重新扫码绑定,后续不会再出现重启后校验失败的问题。

内容的提问来源于stack exchange,提问作者Organiccat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:47:06