version: 20250815

This commit is contained in:
2025-08-15 12:47:58 +00:00
parent 14ff988b0b
commit d18a334626
27 changed files with 2419 additions and 610 deletions

View File

@@ -1,30 +1,103 @@
import CryptoJS from 'crypto-js';
import CryptoJS from 'crypto-js'; // 假设使用crypto-js库
const key = CryptoJS.enc.Utf8.parse(import.meta.env.VITE_APP_KEY);
const iv = CryptoJS.enc.Utf8.parse(import.meta.env.VITE_APP_IV);
// 密钥必须与加密时完全一致(建议从环境变量读取,避免硬编码)
const SECRET_KEY = import.meta.env.VITE_APP_KEY || 'your-secret-key-32bytes'; // 32字节密钥AES-256
const IV = import.meta.env.VITE_APP_IV || '16bytesIvValue!'; // 16字节IV
const crypto = {
encrypt: (str) => {
const encrypted = CryptoJS.AES.encrypt(str, key, {
// 验证密钥和IV长度关键修复
if (SECRET_KEY.length !== 32) {
console.error(`加密密钥长度错误需要32字节实际${SECRET_KEY.length}字节`);
}
if (IV.length !== 16) {
console.error(`IV长度错误需要16字节实际${IV.length}字节`);
}
/**
* 加密函数
* @param {string} data - 要加密的字符串需确保是有效的UTF-8
* @returns {string} 加密后的Base64字符串
*/
export const encrypt = (data) => {
try {
// 确保输入是字符串且是有效的UTF-8
if (typeof data !== 'string') {
throw new Error('加密数据必须是字符串');
}
// 验证UTF-8有效性
new TextDecoder().decode(new TextEncoder().encode(data));
const key = CryptoJS.enc.Utf8.parse(SECRET_KEY);
const iv = CryptoJS.enc.Utf8.parse(IV);
const encrypted = CryptoJS.AES.encrypt(
data,
key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 将加密结果转换为字节数组,然后转换为十六进制字符串
const hexString = CryptoJS.enc.Hex.stringify(encrypted.ciphertext);
return hexString;
},
decrypt: (hexString) => {
// 将十六进制字符串转换回字节数组
const ciphertext = CryptoJS.enc.Hex.parse(hexString);
const encryptedParams = CryptoJS.lib.CipherParams.create({ ciphertext });
const decrypted = CryptoJS.AES.decrypt(encryptedParams, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
);
// 返回Base64格式的密文避免特殊字符问题
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
} catch (error) {
console.error('加密失败:', error);
throw new Error(`加密错误: ${error.message}`);
}
};
export default crypto;
/**
* 解密函数
* @param {string} encryptedData - 加密后的Base64字符串
* @returns {string} 解密后的UTF-8字符串
*/
export const decrypt = (encryptedData) => {
try {
// 验证输入是否为字符串
if (typeof encryptedData !== 'string' || encryptedData.trim() === '') {
throw new Error('解密数据必须是非空字符串');
}
// 验证Base64有效性关键修复
if (!/^[A-Za-z0-9+/=]+$/.test(encryptedData)) {
throw new Error('解密数据不是有效的Base64格式');
}
const key = CryptoJS.enc.Utf8.parse(SECRET_KEY);
const iv = CryptoJS.enc.Utf8.parse(IV);
// 先将Base64转换为CipherParams对象
const cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(encryptedData)
});
const decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// 转换为UTF-8字符串处理可能的编码错误
const result = decrypted.toString(CryptoJS.enc.Utf8);
if (!result) {
throw new Error('解密结果为空,可能是密钥不匹配或数据损坏');
}
// 再次验证UTF-8有效性
new TextDecoder().decode(new TextEncoder().encode(result));
return result;
} catch (error) {
console.error('解密失败:', error);
throw new Error(`解密错误: ${error.message}`);
}
};
export default { encrypt, decrypt };