You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.8 KiB

/**
* 验证加密/解密是否与前端 auth.js 一致
*/
const crypto = require('crypto');
const path = require('path');
const SYSTEM_SALT = new Uint8Array([
0xDA, 0x4A, 0x1F, 0x93, 0xB2, 0x7E, 0x05, 0xC1,
0x38, 0xD9, 0x6A, 0x2B, 0x44, 0xF0, 0x87, 0x3E
]);
function encrypt(password, plaintext) {
const key = crypto.pbkdf2Sync(password, SYSTEM_SALT, 100000, 16, 'sha256');
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv('aes-128-gcm', key, iv);
const encrypted = Buffer.concat([
cipher.update(plaintext, 'utf8'),
cipher.final()
]);
const authTag = cipher.getAuthTag();
const combined = Buffer.concat([iv, encrypted, authTag]);
return combined.toString('base64');
}
function decrypt(b64, password) {
try {
const combined = Buffer.from(b64, 'base64');
const iv = combined.subarray(0, 12);
const authTag = combined.subarray(combined.length - 16);
const ciphertext = combined.subarray(12, combined.length - 16);
const key = crypto.pbkdf2Sync(password, SYSTEM_SALT, 100000, 16, 'sha256');
const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([
decipher.update(ciphertext),
decipher.final()
]);
return decrypted.toString('utf8');
} catch (e) {
return null;
}
}
// ── 测试 ──────────────────────────────────────────────────────────
const testPassword = 'Admin@2025';
const plaintext = 'DARPA_AUTH';
// 测试 1: 加密后解密
const ciphertext = encrypt(testPassword, plaintext);
console.log('密文:', ciphertext);
const decrypted = decrypt(ciphertext, testPassword);
console.log('解密结果:', decrypted);
console.log('测试1 (加密→解密):', decrypted === plaintext ? '通过' : '失败');
// 测试 2: 验证 users.json 中的密文能否解密
const fs = require('fs');
const users = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'users.json'), 'utf8'));
const storedCiphertext = users['woker'].ciphertext;
console.log('\nusers.json 中 woker 的密文:', storedCiphertext);
const result = decrypt(storedCiphertext, testPassword);
console.log('用', testPassword, '解密结果:', result);
console.log('测试2 (文件密文解密):', result === plaintext ? '通过' : '失败');
// 测试 3: 额外测试 base64 编解码一致性
console.log('\nBase64 往返测试:');
const testBytes = Buffer.from([0x00, 0xFF, 0x80, 0x7F, 0xAB, 0xCD]);
const b64 = testBytes.toString('base64');
console.log('原始字节:', testBytes.toString('hex'));
console.log('Base64:', b64);
console.log('解码回:', Buffer.from(b64, 'base64').toString('hex'));