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.
74 lines
2.7 KiB
74 lines
2.7 KiB
/**
|
|
* 重置管理员密码 — 使用与前端 auth.js 完全一致的参数
|
|
*/
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// 与前端 auth.js 一致的参数
|
|
const SYSTEM_SALT = new Uint8Array([
|
|
0xDA, 0x4A, 0x1F, 0x93, 0xB2, 0x7E, 0x05, 0xC1,
|
|
0x38, 0xD9, 0x6A, 0x2B, 0x44, 0xF0, 0x87, 0x3E
|
|
]);
|
|
const PBKDF2_ITERATIONS = 100000;
|
|
const KEY_LENGTH = 16; // AES-128
|
|
const DIGEST = 'sha256';
|
|
const PLAINTEXT = 'DARPA_AUTH';
|
|
|
|
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, PBKDF2_ITERATIONS, KEY_LENGTH, DIGEST);
|
|
const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv);
|
|
decipher.setAuthTag(authTag);
|
|
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function encrypt(password, plaintext) {
|
|
const key = crypto.pbkdf2Sync(password, SYSTEM_SALT, PBKDF2_ITERATIONS, KEY_LENGTH, DIGEST);
|
|
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');
|
|
}
|
|
|
|
// ── 读取 users.json ──
|
|
const usersPath = path.join(__dirname, '..', 'users.json');
|
|
const users = JSON.parse(fs.readFileSync(usersPath, 'utf8'));
|
|
|
|
const storedCT = users['woker'].ciphertext;
|
|
console.log('=== 当前状态 ===');
|
|
console.log('woker 的密文:', storedCT);
|
|
|
|
// 测试可能的旧密码
|
|
const testPwds = ['Worker@2026', 'Admin@2025', 'admin123', 'woker', 'DARPA2025', 'Work@2026'];
|
|
for (const pwd of testPwds) {
|
|
const r = decrypt(storedCT, pwd);
|
|
console.log(' 尝试密码 [' + pwd + ']:', r === PLAINTEXT ? 'OK' : (r || '解密失败'));
|
|
}
|
|
|
|
// ── 重置为 Worker@2026 ──
|
|
const NEW_PASSWORD = 'Worker@2026';
|
|
console.log('\n=== 重置 ===');
|
|
const newCT = encrypt(NEW_PASSWORD, PLAINTEXT);
|
|
console.log('新密码:', NEW_PASSWORD);
|
|
console.log('新密文:', newCT);
|
|
|
|
// 验证新密文可解密
|
|
const verify = decrypt(newCT, NEW_PASSWORD);
|
|
console.log('验证解密:', verify === PLAINTEXT ? '通过' : '失败!');
|
|
|
|
// 更新并写回
|
|
users['woker'].ciphertext = newCT;
|
|
users['woker'].name = '系统管理员';
|
|
fs.writeFileSync(usersPath, JSON.stringify(users, null, 2) + '\n', 'utf8');
|
|
console.log('\nusers.json 已更新!');
|