kdbx-wasm

用 Rust + WebAssembly 打造的高性能 KDBX 4 密码库解析器,浏览器与 Node.js 通用,零依赖、自带完整 TypeScript 类型。

RustWebAssemblyTypeScript

kdbx-wasm 是一个用 Rust 编写、编译到 WebAssemblyKDBX 4 密码数据库解析器,同一份包可以直接跑在浏览器和 Node.js 里,用来读写 KeePass 的 .kdbx 文件。

特性

  • KDBX 4:解析、修改并导出 .kdbx 文件(不支持 3.x 旧格式)
  • 加密算法:AES-256-CBC / ChaCha20
  • 密钥派生:Argon2d / Argon2id / AES-KDF
  • 零依赖:独立发布,无需任何原生 addon
  • TypeScript:完整类型定义,开箱即用
  • 密码默认不出现在查询结果里,需显式传入参数才会返回

支持的 KeePass 特性

特性 状态
AES-256 / ChaCha20 加密
Argon2d / Argon2id / AES-KDF
Gzip 压缩
分组与条目
自定义字段 ✅(普通 Object)
条目历史 ✅(往返保留)
二进制附件 ✅(往返保留,含引用)
标签
密码 + 密钥文件 ✅(原始 / XML v1/v2 / hex)

安装

npm install kdbx-wasm

Node.js 需要 19+(仅 ESM,随机数依赖全局 crypto);Node 18 上需自行 polyfill globalThis.crypto

快速上手

Node.js

WASM 模块在 import 时同步加载,无需调用 init()

import { readFileSync } from 'node:fs';
import { KdbxDatabase, isKdbxFile, getFileInfo } from 'kdbx-wasm';

const data = new Uint8Array(readFileSync('passwords.kdbx'));

// 快速校验
if (!isKdbxFile(data)) throw new Error('Not a valid KDBX file');

// 不解密即可窥探头部信息
const info = getFileInfo(data);
console.log(info.encryptionAlgorithm); // "AES-256"
console.log(info.kdfAlgorithm);        // "Argon2id"

// 打开数据库
const db = new KdbxDatabase(data, 'master-password');

// 列出所有条目(默认不含密码)
for (const entry of db.getEntries()) {
  console.log(entry.title, '-', entry.username);
}

// 导出(可换主密码)
writeFileSync('exported.kdbx', db.toBytes('new-password'));

浏览器

浏览器端 WASM 异步加载,首次使用前调用一次默认导出的 init()

import init, { KdbxDatabase, isKdbxFile } from 'kdbx-wasm';
await init();

const data = new Uint8Array(await file.arrayBuffer());
if (isKdbxFile(data)) {
  const db = new KdbxDatabase(data, 'master-password');
  for (const entry of db.getEntries()) {
    console.log(entry.title, entry.username);
  }
}

包的 exports 字段会自动按环境路由:Node 走同步加载入口,浏览器 / 打包器走 fetch 版入口。

常用操作

// 全文搜索(标题、用户名、URL、备注、标签、自定义字段值)
const results = db.searchEntries('github');

// 创建 / 修改条目
const uuid = db.createEntry(groupUuid, 'New Service', 'generated-password');
db.setEntryUsername(uuid, 'newuser');
db.setEntryCustomField(uuid, 'OTP', '123456');

// 分组操作
const groupId = db.createGroup('Work', db.rootGroupUuid);
db.moveEntry(uuid, groupId);

// 到期时间(RFC 3339)
db.setEntryExpires(uuid, '2026-12-31T23:59:59Z');

条目历史、二进制附件(含引用)在往返读写中都会完整保留;导出的文件可能比原文件略小,这是未保留的 KeePass 内部冗余数据(如未使用的自定义图标)所致,属正常现象。

安全设计

  • 所有密码学运算(AES、ChaCha20、Argon2、HMAC)都在 WASM 沙箱内完成;
  • 查询结果默认剥离密码字段,必须显式请求才返回;
  • Rust 侧 SecString / SecVec 使用 zeroize 在丢弃时清零内存。

从源码构建

rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli
./scripts/build-wasm.sh

许可证

MIT

0%