工具指南28-在线TOTP动态验证码生成器

双因素认证(2FA)里最常见的就是那个每隔 30 秒自动刷新的 6 位数字。扫个二维码,手机上弹出一串数字,登录时输进去,整个流程顺畅到很多人从没想过它背后是怎么工作的。

这篇文章拆解 TOTP 的原理,介绍 在线 TOTP 动态验证码生成器 的使用场景,并给需要自己实现 2FA 的开发者提供一份可直接参考的代码。

TOTP 是什么

TOTP 全称 Time-based One-Time Password,基于 RFC 6238 标准。它的核心思路很简单:把一个密钥(Secret)和当前时间戳组合起来,通过 HMAC-SHA1 算法生成一个短期有效的数字。

计算过程分三步:

  1. 时间步长:把当前 Unix 时间戳除以 30(秒),得到一个整数 T。每 30 秒 T 递增一次。
  2. HMAC 计算:用 Base32 解码后的密钥对 T 的 8 字节大端整数做 HMAC-SHA1,得到 20 字节摘要。
  3. 截断取码:取摘要最后一字节的低 4 位作为偏移量,从该偏移量起取 4 字节,对 10^6 取模,得到 6 位数字。

这个算法的关键特性:服务端和客户端只需要共享一次密钥,之后无需任何网络通信,就能独立算出相同的验证码。只要时钟同步,两边算出来的数永远一致。

工具使用场景

TOTP 动态验证码生成器 在以下场景比手机 App 更方便:

测试和开发:自己写 2FA 功能时,需要快速验证 Secret 是否配置正确、前后端算法有没有对上。打开工具,粘入 Secret,立刻看到当前 OTP 和剩余有效时间,比掏出手机来回核对快得多。

临时设备:在没有安装 Authenticator App 的电脑上需要登录某个账号,用在线工具可以临时生成验证码。注意:这只适用于你完全信任该设备和网络环境的场合。

批量验证:自动化测试脚本里需要模拟 2FA 登录,直接在工具里验证 Secret 的正确性,比在代码里调试更直观。

恢复场景:手机丢失或者换机时,如果保存了原始 Secret(Base32 字符串),用在线工具可以立即恢复访问,不依赖备份设备。

工具的核心功能

打开 https://anyfreetools.com/tools/totp-generator,界面分为两个区域:

生成器:输入 Base32 格式的 Secret,工具实时显示当前 6 位 OTP 和一个倒计时进度条,倒计时到 0 时自动刷新下一个 OTP。支持自定义时间步长(默认 30 秒)和 OTP 位数(默认 6 位)。

Secret 生成:如果你正在给自己的系统添加 2FA,可以用工具内置的随机 Secret 生成功能,生成符合规范的 Base32 密钥,直接复制使用。

全部计算在浏览器本地完成,Secret 不会上传到服务器。

和 Google Authenticator 的区别

Google Authenticator、Authy、1Password 等 App 实现的也是同一套 RFC 6238 标准,生成的验证码和在线工具完全一致。区别在于:

维度手机 Authenticator App在线工具
安全性更高(本地存储,离线可用)适中(本地计算,但需要浏览器环境)
便利性随时可用,不依赖电脑需要输入 Secret,适合临时使用
适合场景日常 2FA 登录开发测试、临时访问、故障恢复
多账号管理App 内统一管理每次需要手动输入 Secret

重要提醒:在线工具适合开发调试和临时场景。对于日常账号的 2FA 验证,建议使用本地 Authenticator App,不要把 Secret 长期保存在任何在线服务中。

开发者:给自己的系统集成 TOTP

如果你在开发一个需要 2FA 的系统,下面是前后端各自的实现方式。

后端:Node.js

otpauth 库,几行代码搞定:

npm install otpauth
import * as OTPAuth from "otpauth";

// 生成新用户的 Secret
function generateSecret(username) {
  const totp = new OTPAuth.TOTP({
    issuer: "MyApp",
    label: username,
    algorithm: "SHA1",
    digits: 6,
    period: 30,
    secret: OTPAuth.Secret.fromRandom(20),
  });

  return {
    secret: totp.secret.base32, // 保存到数据库
    otpauthUrl: totp.toString(), // 生成二维码用这个 URL
  };
}

// 验证用户输入的 OTP
function verifyOTP(secret, token) {
  const totp = new OTPAuth.TOTP({
    algorithm: "SHA1",
    digits: 6,
    period: 30,
    secret: OTPAuth.Secret.fromBase32(secret),
  });

  // delta 表示时间窗口偏移,±1 容忍 30 秒误差
  const delta = totp.validate({ token, window: 1 });
  return delta !== null;
}

otpauthUrl 格式是 otpauth://totp/MyApp:username?secret=XXX&issuer=MyApp,把这个字符串生成二维码,用户用 Google Authenticator 扫描即可绑定。

后端:Python

import pyotp
import qrcode

# 生成 Secret
secret = pyotp.random_base32()

# 创建 TOTP 对象
totp = pyotp.TOTP(secret)

# 生成二维码 URL
otpauth_url = totp.provisioning_uri(
    name="user@example.com",
    issuer_name="MyApp"
)

# 验证用户输入
def verify(token: str) -> bool:
    # valid_window=1 容忍 ±30 秒时钟偏差
    return totp.verify(token, valid_window=1)

print(f"Secret: {secret}")
print(f"OtpAuth URL: {otpauth_url}")
print(f"Current OTP: {totp.now()}")

前端:显示绑定二维码

用户首次开启 2FA 时,后端生成 Secret 并返回 otpauthUrl,前端用 qrcode 库渲染二维码:

import QRCode from "qrcode";

async function renderQRCode(otpauthUrl, canvasElement) {
  await QRCode.toCanvas(canvasElement, otpauthUrl, {
    width: 200,
    margin: 2,
  });
}

用户用 Authenticator App 扫描后,让他输入一次当前 OTP 来确认绑定成功,再把 Secret 存入数据库——这一步验证很重要,防止因为 Secret 传输错误导致用户被锁死。

数据库设计

TOTP 集成需要注意几个字段:

ALTER TABLE users ADD COLUMN
  totp_secret VARCHAR(64),           -- Base32 Secret,加密存储
  totp_enabled BOOLEAN DEFAULT FALSE, -- 是否已开启 2FA
  totp_verified_at TIMESTAMP,        -- 首次验证成功时间
  totp_backup_codes TEXT;            -- 备用恢复码(JSON 数组,哈希存储)

备用恢复码容易被忽视,但对用户很重要。生成 8-10 个随机字符串,哈希后存库,用户丢失设备时可以用来解除 2FA。每个备用码只能使用一次,使用后标记为已消耗。

常见问题

OTP 不匹配怎么办:99% 是时钟不同步。服务器时间偏差超过 30 秒就会导致验证失败。验证逻辑里加 window: 1(允许前后各一个时间步长)可以容忍 30 秒误差,基本够用。如果偏差更大,检查服务器 NTP 配置。

Secret 存储安全:Secret 是凭据,和密码一样敏感。不要明文存储,建议用 AES 加密后再入库,加密密钥走环境变量或密钥管理服务(KMS)。

多设备绑定:同一个 Secret 可以同时在多个设备上使用,因为算法是确定性的,只要 Secret 相同,任何设备都能算出相同的 OTP。这既是优点(多设备备份)也是风险(Secret 泄露后任何人都能生成 OTP)。

TOTP vs HOTP:HOTP(HMAC-based OTP,RFC 4226)用计数器代替时间戳,每次使用后计数器递增。优点是不依赖时钟同步,缺点是状态同步复杂、容易计数器漂移。日常 2FA 场景 TOTP 更主流。


TOTP 是一个设计得很优雅的协议:只需一次密钥交换,之后完全离线运行,没有中间人,没有网络依赖。理解它的原理,一方面有助于正确实现 2FA,另一方面也帮你判断哪些场景下在线工具可以用、哪些场景下安全边界在哪里。

需要快速生成或验证 OTP,用 在线 TOTP 生成器;自己系统要集成 2FA,参考上面的代码,基本可以直接跑通。


工具指南系列

工具指南1-在线图片压缩 | 工具指南2-JSON格式化 | 工具指南3-正则测试 | 工具指南4-二维码生成 | 工具指南5-Base64 | 工具指南6-JWT解码 | 工具指南7-时间戳转换 | 工具指南8-密码生成器 | 工具指南9-URL编解码 | 工具指南10-哈希生成器 | 工具指南11-JSON转TypeScript | 工具指南12-Cron解析器 | 工具指南13-颜色转换 | 工具指南14-SQL格式化 | 工具指南15-Markdown预览 | 工具指南16-JSON对比 | 工具指南17-Token计数器 | 工具指南18-OCR文字识别 | 工具指南19-CSS渐变生成器 | 工具指南20-UUID生成器 | 工具指南21-HTML转JSX | 工具指南22-WebSocket测试 | 工具指南23-CSV转JSON | 工具指南24-Box Shadow生成器 | 工具指南25-Favicon生成器 | 工具指南26-子网计算器 | 工具指南27-Mock数据生成器