实现服务端解密的 KeePass 网页查看器,包含登录门户口令与验证码、RSA+会话级 AES 加密通道、审计日志持久化、HTTPS 自动证书、Docker 部署配置及端到端测试。
56 行
2.3 KiB
JavaScript
56 行
2.3 KiB
JavaScript
'use strict';
|
|
// 自测:生成一个 KDBX4(主密码 + keyfile,KDF=Argon2),再用服务器的同款逻辑复读,
|
|
// 验证 Argon2 胶水层 + keyfile 服务端读取在 Node 下确实可用。
|
|
// 注意:本机 Windows Defender 会拦截 .key 扩展名写入,故自测用 .bin 扩展名 + 临时目录,
|
|
// 与容器内 /app/vault/vault.key 的解密逻辑完全一致。
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const { Kdbx, Credentials, ProtectedValue, Consts } = require('kdbxweb');
|
|
const { loadDatabase } = require('./kdbxlib');
|
|
|
|
(async () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'kdbx-selftest-'));
|
|
const kdbxPath = path.join(dir, '_selftest.kdbx');
|
|
const keyPath = path.join(dir, '_selftest.bin'); // 非 .key,规避本地安全软件拦截
|
|
|
|
// 32 字节随机密钥文件
|
|
const keyBytes = crypto.randomBytes(32);
|
|
fs.writeFileSync(keyPath, keyBytes);
|
|
const keyAb = keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength);
|
|
|
|
const masterPassword = 'TestMaster123!';
|
|
const creds = new Credentials(ProtectedValue.fromString(masterPassword), keyAb);
|
|
|
|
const db = Kdbx.create(creds, 'SelfTestDB');
|
|
db.setKdf(Consts.KdfId.Argon2); // 强制用 Argon2,专门验证 Argon2 胶水
|
|
const group = db.createGroup(db.getDefaultGroup(), 'Login');
|
|
const e = db.createEntry(group);
|
|
e.fields.set('Title', 'Example');
|
|
e.fields.set('UserName', 'alice');
|
|
e.fields.set('Password', ProtectedValue.fromString('s3cret'));
|
|
e.fields.set('URL', 'https://example.com');
|
|
e.fields.set('Notes', 'self-test note');
|
|
|
|
const saved = await db.save();
|
|
fs.writeFileSync(kdbxPath, Buffer.from(saved));
|
|
console.log('已生成测试库:', kdbxPath);
|
|
|
|
// 用服务器同款逻辑重新加载
|
|
const rec = await loadDatabase(kdbxPath, keyPath, masterPassword);
|
|
console.log('解锁成功,库名:', rec.name, '条目数:', rec.items.length);
|
|
|
|
const ok = rec.items.some(
|
|
(i) => i.title === 'Example' && i.username === 'alice' && i.password === 's3cret'
|
|
);
|
|
if (!ok) {
|
|
console.error('❌ 自测失败:条目内容不匹配');
|
|
process.exit(1);
|
|
}
|
|
console.log('✅ 自测通过:Argon2 + keyfile 解密在 Node 下可用');
|
|
})().catch((e) => {
|
|
console.error('❌ 自测异常:', e);
|
|
process.exit(1);
|
|
});
|