npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@adep/crypto

v0.1.0

Published

云函数沙箱内可用的密码学工具集(HS256 JWT / PBKDF2 口令哈希 / AES-256-GCM),纯 WebCrypto 零依赖,替代 jsonwebtoken + bcrypt + node:crypto。

Readme

@adep/crypto — 云函数沙箱内可用的密码学工具集

JWT(HS256)/ 口令哈希(PBKDF2-SHA256)/ 对称加密(AES-256-GCM)。纯 WebCrypto、零依赖、零 Node API——adep 的云函数沙箱没有 node:*、也没有原生 addon,本包是把沙箱里已注入的 WebCrypto 封装成可直接用的形式。

npm install @adep/crypto
# 或
pnpm add @adep/crypto

在 adep 平台上,本包已进沙箱内置依赖白名单(@adep/[email protected]+ / 平台缺省配置),函数里直接 import 即可,无需装依赖。

它替代什么

| 本包 | 替代 | 为什么替代品在沙箱里跑不了 | | --- | --- | --- | | jwt.ts | jsonwebtoken | 依赖 node:crypto 的同步 HMAC | | password.ts | bcrypt | 原生 C++ addon,沙箱无法加载 | | aes.ts | node:cryptocreateCipheriv | node:* 不可达 |

对从 Node / Nuxt / Workers 迁过来的项目,这三件事几乎必然用到;缺了它们,每个项目都要在自己的 _shared/ 里各写一份——同一算法多份拷贝必然静默分叉

JWT

import { signJwt, verifyJwt, tryVerifyJwt, JwtError } from '@adep/crypto'

const token = await signJwt({ sub: 'user-1', role: 'admin' }, ctx.env.JWT_SECRET, {
  expiresIn: '2h', // 也接受 expiresInSeconds;裸数字字符串('45')= 秒
})

try {
  const claims = await verifyJwt<{ sub: string; role: string }>(token, ctx.env.JWT_SECRET)
  // claims.sub / claims.role
} catch (error) {
  // JwtError.code 区分 'expired' 与 'tampered' 等
  if (error instanceof JwtError) return new Response(error.code, { status: 401 })
  throw error
}

// 仅在「所有失败一律当未授权」时使用(失败返回 null,不抛)
const maybe = await tryVerifyJwt(token, ctx.env.JWT_SECRET)
  • HS256;签发与校验两侧都把 alg 钉死,防 alg: none 与算法降级。
  • 支持 exp / nbf / iat / iss / aud 校验;clockToleranceSeconds 放行时钟漂移(缺省 0)。
  • verifyJwt 绝不返回 null——避免调用方漏判。

口令哈希

import { hashPassword, verifyPassword, isBcryptHash, needsRehash } from '@adep/crypto'

const stored = await hashPassword(password) // 'pbkdf2$sha256$210000$<salt>$<hash>'
const ok = await verifyPassword(password, stored)

// 存量 bcrypt 口令的兼容分支:校验通过后就地升级,不强制重置
if (isBcryptHash(stored) && (await verifyBcrypt(password, stored))) {
  await updatePassword(userId, await hashPassword(password))
} else if (needsRehash(stored)) {
  await updatePassword(userId, await hashPassword(password))
}
  • PBKDF2-SHA256,缺省 210k 迭代 / 16B salt / 32B key,参数随哈希串自描述(HashPasswordOptions 可调)。
  • 校验走恒定时间比较;格式非法、拿到 bcrypt 哈希、算法不匹配一律返回 false
  • 空口令被拒绝——空口令哈希一旦落库,任何空输入都能通过校验。

对称加密

import { encryptSecret, decryptSecret } from '@adep/crypto'

const cipher = await encryptSecret('sk-live-xxxx', ctx.env.CRYPTO_SECRET)
const plain = await decryptSecret(cipher, ctx.env.CRYPTO_SECRET) // string | null
  • AES-256-GCM,密文格式 iv:authTag:ciphertext(base64),与 Node 侧 createCipheriv 实现逐字节兼容——迁移时既有密文无需重加密。
  • 密钥由 deriveAesKey(secret) 从口令串派生(SHA-256(secret),与 Node 版 getEncryptionKey 等价)。
  • decryptSecret 按「未配置」语义返回 null(空串 / 格式非法 / 认证失败——密钥轮换后旧密文即视为未配置,重存一次即可);需要区分「格式错」与「被篡改」时用 decryptSecretStrict(任何失败都抛)。
  • secretEquals(a, b) 恒定时间比较两个密文串,供「值有没有变」的判断。
  • 同一密钥下绝不可复用 IV;本包每次加密随机取 IV。

编码工具

base64ToBytes · bytesToBase64 · base64UrlToBytes · bytesToBase64Url · base64UrlToUtf8 · utf8ToBase64Url · utf8ToBytes · bytesToUtf8 · timingSafeEqual · EMPTY_BYTES

说明

  • 零运行时依赖;沙箱已注入 crypto / subtle,本包只是它的封装。
  • 类型契约见 packages/crypto/dist/*.d.ts;实现见仓库 packages/crypto/src/