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

passvault-crypto

v0.1.0

Published

PassVault 零知识加密模块:PBKDF2 密钥派生 + TweetNaCl secretbox 认证加密,微信小程序与 H5 共用

Readme

passvault-crypto

密小本(PassVault) 的零知识加密核心——纯 JavaScript,无框架依赖,可在任意 JS 环境运行(浏览器 / uni-app / 小程序 / Node)。

零知识密码管理的全部密码学逻辑都集中在这个包里,代码量不足 200 行,欢迎任何人独立审计。

  • 密钥派生:PBKDF2-SHA256,100,000 次迭代
  • 数据加密:TweetNaCl secretbox(XSalsa20-Poly1305 认证加密)
  • 运行时零依赖(crypto-js / tweetnacl 为依赖,均无内建后门能力——随机源可强制接管,见下文)

安装

npm install passvault-crypto

(源码见 GitHub。)

API

| 函数 | 说明 | |---|---| | deriveMasterKey(masterPassword, salt, iterations) | 主密码 → masterKey(32 字节)。只在客户端调用,结果绝不离开内存 | | deriveAuthHash(masterKey, username) | masterKey → 登录凭证 authHash(hex)。这是服务器唯一见过的「密码派生物」 | | generateDek() | 生成每用户一把数据密钥 DEK(32 字节随机) | | randomSalt() | 生成 16 字节 base64 盐 | | wrapDek(dek, masterKey) | 用 masterKey 包裹 DEK(secretbox),返回 { wrappedDek, wrapNonce } | | unwrapDek(wrappedDek, wrapNonce, masterKey) | 解包;主密码错误返回 null(认证标签校验失败),不抛异常 | | encryptItem(item, dek) | 条目 JSON → { ciphertext, nonce }(整条认证加密) | | decryptItem(ciphertext, nonce, dek) | 解密;篡改/密钥不匹配返回 null | | installSecureRandom(fetchBytesAsync) | 强制接管随机源,返回 ensureRandom(bytes) |

密钥链

主密码(只存在用户设备内存)
   │ PBKDF2-SHA256(密码, salt, 10万次)
   ▼
masterKey ──HMAC-SHA256──► authHash(上服务器,服务器再 bcrypt 后存库)
   │
   └─ 解开 wrappedDek ──► DEK ──secretbox──► 条目密文(上服务器)
  • 服务器只见:authHash(bcrypt 后)、wrappedDek、条目密文
  • 改主密码 = 用新 masterKey 重包裹 DEK,历史数据零重加密
  • 忘记主密码 = 数据永久不可找回(这是设计,不是缺陷)

如何审计我们没有留后门

  1. 读完全部源码:src/index.js 一个文件,密码学路径只有派生(PBKDF2)、认证(HMAC)、加密(secretbox)、随机数(nacl.randomBytes)四种原语
  2. 检查随机源:包内唯一可能引入后门的位置是随机数。installSecureRandom 强制替换 nacl 的 PRNG 为你提供的安全源——没有用系统随机源的默认路径,也就没有"悄悄换随机数"的空间(这也是为什么小程序/APP 端必须调用它,见下)
  3. 验证认证加密:decryptItem/unwrapDek 对任何篡改返回 null(Poly1305 标签校验),不存在"密文可被改写"的路径
  4. 跑测试:npm test(node --test,覆盖派生⇄验证、包裹⇄解包、加密⇄解密、篡改拒绝、随机池)

随机源红线(接入方必读)

加密的安全性 = 随机源的安全性。tweetnacl 默认退化为 Math.random(不安全)时不会报错,只会静默产出弱密钥。

  • 小程序 / APP:必须在运行时调用 installSecureRandom(你的安全随机获取函数),且每次 generateDek/randomSalt/wrapDek/encryptItem 之前 await ensureRandom(...)——随机池是消费式的,池空时 nacl 会抛错提醒
  • H5 / Node:无需接管(crypto.getRandomValues 自动生效)
import { installSecureRandom, generateDek } from 'passvault-crypto';

const ensureRandom = installSecureRandom(async (n) => {
  // 小程序示例:从 uni.getRandomValues 取 n 字节的真随机数
  // 实现见密小本 app 端 random.js
});

await ensureRandom();
const dek = generateDek(); // 安全

License

MIT