@epic-web/totp

中文文档
4.0.1发布于 2025/02/26MITTypeScriptES Module构建来源已验证近 30 天下载 15.8万

使用基于HMAC的一次性密码(HOTP)算法,创建并验证加密安全的基于时间的一次性密码(TOTP).

中文使用文档
文档目录15 节
  1. 问题
  2. 这个解决方案
  3. 术语
  4. 使用量
  5. 2FA 代码
  6. 核实电子邮件/电话号码的所有权
  7. 增强安全的自定义字符集
  8. 为什么字符集事项
  9. 主要认证形式的可能性
  10. 自定义字符集的使用
  11. API 密码
  12. generateTOTP
  13. verifyTOTP
  14. getTOTPAuthUri
  15. 许可证

@epic-web/top

轻松支持应用程序中的双因子认证(2FA) .

创建和验证加密安全、基于时间的一次性密码 (TOTP)使用基于HMAC的一次性密码(HOTP)算法.

npm install @epic-web/totp

Build Status MIT License Code of Conduct

问题

您想要支持 2FA 客户端或生成安全的一次性密码到其它处 验证您的用户.

这个解决方案

这是从 编号 (麻省理工学院)

主要动机是支持一个比 SHA-1 (虽然Google认证员只支持) SHA-1使用寿命较长的检察官办公室 比较安全的算法). 维护者没有积极回应问题或 数年内调取请求.

守则的现代化作了一些改进(最近一次公布) 2014年),并改进API. 但核心算法不变.

术语

  • 检察官办公室: 一个时间密码
  • 现场直播: 基于 HMAC 的一次性密码
  • TOTP 调试: 基于时间的一次性密码

这个 TOTP 调试 我们通常用于核查代码。 这个可以使用 2FA(双要素认证),但也用于电子邮件验证, 密码重置等.

使用量

此套件输出出三种方法:

  • generateTOTP - 这会产生检察官办公室,并返回用于 生成它.
  • verifyTOTP - 这验证了检察官办公室对用来生成它的配置.
  • getTOTPAuthUri - 生成URI,用于将检察官办公室添加到 认证软件.

2FA 代码

以下是生成 2FA auth URI 的典型过程(用户可以添加) 他们的认证程序.

import { generateTOTP, getTOTPAuthUri, verifyTOTP } from '@epic-web/totp'

// Here's how to use the default config. All the options are returned:
const { secret, period, digits, algorithm } = await generateTOTP()
const otpUri = getTOTPAuthUri({
    period,
    digits,
    algorithm,
    secret,
    accountName: user.email,
    issuer: 'Your App Name',
})
// check docs below for customization options.

// optional, but recommended: import * as QRCode from 'qrcode'
// const qrCode = await QRCode.toDataURL(otpUri)

// now you can display the QR code and the URI to the user and let them enter
// their code from their authenticator app.
// however you get the code from the user, do it:
const code = await getCodeFromUser()

// now verify the code:
const isValid = await verifyTOTP({ otp: code, secret, period, digits, algorithm })

// if it's valid, save the secret, period, digits, and algorithm to the database
// along with who it belongs to and use this info to verify the user when they
// login or whatever.

核实电子邮件/电话号码的所有权

以下是一次性验证用户电子邮件/电话的典型过程 编号/etc:

import { generateTOTP, verifyTOTP } from '@epic-web/totp'

const { otp, secret, digits, period, algorithm } = await generateTOTP({
    algorithm: 'SHA-256', // more secure algorithm should be used with longer-lived OTPs
    period: 10 * 60, // 10 minutes
})

await sendOtpToUser({
    email: user.email,
    otp,
    secret,
    digits,
    period,
    algorithm,
})
await saveVerificationToDatabase({
    secret,
    digits,
    period,
    algorithm,
    target: user.email,
})

// when the user gives you the code (however you do that):
const code = await getCodeFromUser()

// now verify the code:
const userCodeConfig = await getVerificationFromDatabase({
    target: user.email,
})
const isValid = await verifyTOTP({ otp: code, ...userCodeConfig })

if (isValid) {
    await deleteVerificationFromDatabase({ target: user.email })
    // allow the user to proceed
} else {
    // show an error
}

增强安全的自定义字符集

为什么字符集事项

当涉及到安全时,每一点的 en都算数. 环测量 还有你的检察官办公室的安全 传统TOTP 设置经常使用6位数字代码,提供一百万(10^6) 组合。 此执行的默认行为 。 虽然如此 强壮,还有改进的余地.

通过引入自定义字符集特性,可以指数化 增加检察官办公室的肽,使其更加安全 野蛮人的攻击 例如,如果将字符集扩展为包含 26 大写字母和10个数字,一个6个字符的检察官办公室将拥有36^6=21亿 组合。 当与利率限制机制配对时, 此配置 变得几乎不受野蛮武力攻击.

主要认证形式的可能性

随着这种复杂性的增加,从理论上讲,TOTP可以作为主要形式: 认证,而不仅仅是第二个因素。 这特别有用 要求加强安全的申请.

自定义字符集的使用

除了现有的选项外,您还可以在两个选项中指定一个字符集 generateTOTP 财务报告和审定财务报表 verifyTOTP。 。 。 .

以下是您如何生成自定义字符集的 OTP :

import { generateTOTP, verifyTOTP } from '@epic-web/totp'

const { otp, secret, period, digits, algorithm, charSet } = await generateTOTP({
    charSet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', // custom character set
})

// Remember to save the charSet to your database as well.

// To verify
const isValid = await verifyTOTP({
    otp,
    secret,
    period,
    digits,
    algorithm,
    charSet,
})

顺便说一句,你可能要排除字母O和数字0到 方便用户输入代码.

API 密码

这个库是用 jsdoc所以希望你的编辑支持 给你看这些东西,但以防万一,这里:

generateTOTP

/**
 * Creates a time-based one-time password (TOTP). This handles creating a random
 * secret (base32 encoded), and generating a TOTP for the current time. As a
 * convenience, it also returns the config options used to generate the TOTP.
 *
 * @param {Object} [options] Configuration options for the TOTP.
 * @param {number} [options.period=30] The number of seconds for the OTP to be
 * valid. Defaults to 30.
 * @param {number} [options.digits=6] The length of the OTP. Defaults to 6.
 * @param {string} [options.algorithm='SHA-1'] The algorithm to use. Defaults to
 * SHA-1.
 * @param {string} [options.secret] The secret to use for the TOTP. It should be
 * base32 encoded (you can use https://npm.im/thirty-two). Defaults to a random
 * secret: base32.encode(crypto.randomBytes(10)).toString().
 * @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
 * @returns {Promise<{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}>}
 * The OTP, secret, and config options used to generate the OTP.
 */

verifyTOTP

/**
 * Verifies a time-based one-time password (TOTP). This handles decoding the
 * secret (base32 encoded), and verifying the OTP for the current time.
 *
 * @param {Object} options The otp, secret, and configuration options for the
 * TOTP.
 * @param {string} options.otp The OTP to verify.
 * @param {string} options.secret The secret to use for the TOTP.
 * @param {number} [options.period] The number of seconds for the OTP to be valid.
 * @param {number} [options.digits] The length of the OTP.
 * @param {string} [options.algorithm] The algorithm to use.
 * @param {string} [options.charSet] The character set to use, defaults to the numbers 0-9.
 * @param {number} [options.window] The number of OTPs to check before and after
 * the current OTP. Defaults to 1.
 *
 * @returns {Promise<{delta: number}|null>} an object with "delta" which is the delta
 * between the current OTP and the OTP that was verified, or null if the OTP is
 * invalid.
 */

getTOTPAuthUri

/**
 * Generates a otpauth:// URI which you can use to generate a QR code or users
 * can manually enter into their password manager.
 *
 * @param {Object} options Configuration options for the TOTP Auth URI.
 * @param {number} options.period The number of seconds for the OTP to be valid.
 * @param {number} options.digits The length of the OTP.
 * @param {string} options.algorithm The algorithm to use.
 * @param {string} options.secret The secret to use for the TOTP Auth URI.
 * @param {string} options.accountName A way to uniquely identify this Auth URI
 * (in case they have multiple of these).
 * @param {string} options.issuer The issuer to use for the TOTP Auth URI.
 *
 * @returns {string} The OTP Auth URI
 */

许可证

麻省理工学院

版本与发布记录

@epic-web/totp 共发布 20 个版本,首次发布于 2023/08/03;过去 12 个月发布了 0 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.0.1latest2025/02/261.7 年前
4.0.02025/02/251.7 年前
3.1.02025/02/181.7 年前
3.0.22025/02/161.7 年前
3.0.12025/02/161.7 年前
3.0.02025/02/151.7 年前

关于 @epic-web/totp 的常见问题

@epic-web/totp 是什么?

使用基于HMAC的一次性密码(HOTP)算法,创建并验证加密安全的基于时间的一次性密码(TOTP).

如何安装 @epic-web/totp?

在项目目录运行 npm install @epic-web/totp,或使用 pnpm add / yarn add / bun add。

@epic-web/totp 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@epic-web/totp 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@epic-web/totp 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@epic-web/totp 可以商用吗?

@epic-web/totp 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@epic-web/totp 的下载量有多少?

根据 npm 官方下载统计,@epic-web/totp 在 2026/10/14 – 2026/11/12 这 30 天内被下载 158,359 次,日均约 5,279 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@epic-web/totp 还在维护吗?

最新版本 4.0.1 发布于 2025/02/26(1.7 年前);至今共发布 20 个版本,其中过去 12 个月发布了 0 个;首次发布于 2023/08/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。