| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // 详细测试CryptoJS兼容的加密解密
- const CryptoJS = require('crypto-js');
- // 测试不同的加密方法和后端解密模拟
- console.log('=== 测试1: 标准CryptoJS加密 ===');
- const credentials = { username: 'admin', password: 'password123' };
- const secretKey = 'MyDifficultPassw';
- // 前端加密
- const encrypted = CryptoJS.AES.encrypt(JSON.stringify(credentials), secretKey);
- const base64String = encrypted.toString();
- console.log('加密结果:', base64String);
- // 检查是否以'Salted__'开头
- const rawData = Buffer.from(base64String, 'base64');
- const header = rawData.slice(0, 8).toString('utf8');
- console.log('前8字节:', header, '(是否为Salted__):', header === 'Salted__');
- // 尝试后端的第一种解密方式(CryptoJS格式)
- try {
- // 提取盐值和加密数据
- const salt = rawData.slice(8, 16); // 8字节盐值
- const encryptedData = rawData.slice(16); // 加密数据
-
- console.log('提取的盐值:', salt.toString('hex'));
- console.log('加密数据长度:', encryptedData.length);
-
- // 在Node.js中模拟PBKDF2派生密钥和IV的过程
- // 这里我们使用一种近似的方法来验证CryptoJS格式
- const decryptedWithCryptoJS = CryptoJS.AES.decrypt(base64String, secretKey).toString(CryptoJS.enc.Utf8);
- console.log('使用CryptoJS直接解密结果:', decryptedWithCryptoJS);
-
- if (decryptedWithCryptoJS === JSON.stringify(credentials)) {
- console.log('✅ CryptoJS格式解密成功');
- } else {
- console.log('❌ CryptoJS格式解密失败');
- }
- } catch (e) {
- console.log('❌ CryptoJS格式解密异常:', e.message);
- }
- console.log('\n=== 测试2: 手动构造AES/CBC/PKCS5Padding加密 ===');
- // 尝试更精确地匹配后端解密逻辑
- try {
- const CryptoJS = require('crypto-js');
-
- // 使用与后端一致的参数进行加密
- const key = CryptoJS.enc.Utf8.parse(secretKey);
- const iv = CryptoJS.enc.Utf8.parse('1234567812345678'); // 固定IV用于测试
-
- const encryptedCustom = CryptoJS.AES.encrypt(JSON.stringify(credentials), key, {
- iv: iv,
- mode: CryptoJS.mode.CBC,
- padding: CryptoJS.pad.Pkcs7
- });
-
- const base64Custom = encryptedCustom.toString();
- console.log('自定义加密结果:', base64Custom);
-
- // 检查是否以'Salted__'开头
- const rawDataCustom = Buffer.from(base64Custom, 'base64');
- const headerCustom = rawDataCustom.slice(0, 8).toString('utf8');
- console.log('自定义加密前8字节:', headerCustom, '(是否为Salted__):', headerCustom === 'Salted__');
-
- // 尝试解密
- const decryptedCustom = CryptoJS.AES.decrypt(base64Custom, key, {
- iv: iv,
- mode: CryptoJS.mode.CBC,
- padding: CryptoJS.pad.Pkcs7
- }).toString(CryptoJS.enc.Utf8);
-
- console.log('自定义解密结果:', decryptedCustom);
- console.log('自定义加密解密是否成功:', decryptedCustom === JSON.stringify(credentials));
-
- } catch (e) {
- console.log('❌ 自定义加密解密失败:', e.message);
- }
- console.log('\n=== 测试3: 模拟后端解密CryptoJS格式的逻辑 ===');
- // 由于Node.js环境无法完全模拟Java的解密过程,
- // 让我们创建一个测试来模拟Java解密CryptoJS格式的步骤
- // CryptoJS的加密过程大致如下:
- // 1. 生成8字节随机盐值
- // 2. 使用'U2FsdGVkX1'作为前缀 + 盐值 + 加密数据
- // 3. 对盐值和密码进行PBKDF2派生,得到密钥和IV
- // 4. 使用AES/CBC/PKCS5Padding加密数据
- // 我们可以通过CryptoJS来验证这种格式
- const saltedEncrypted = CryptoJS.AES.encrypt(JSON.stringify(credentials), secretKey);
- console.log('Salted格式加密:', saltedEncrypted.toString());
- // 验证是否可以正确解密
- const saltedDecrypted = CryptoJS.AES.decrypt(saltedEncrypted.toString(), secretKey).toString(CryptoJS.enc.Utf8);
- console.log('Salted格式解密:', saltedDecrypted);
- console.log('Salted格式是否成功:', saltedDecrypted === JSON.stringify(credentials));
- console.log('\n=== 结论 ===');
- console.log('前端和后端都应该使用相同的密钥:', secretKey);
- console.log('如果仍有问题,可能是后端解密算法与CryptoJS格式不完全兼容');
|