Files
sbu4pe/src/utils/crypto/index.js
2025-08-15 12:47:58 +00:00

104 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import CryptoJS from 'crypto-js'; // 假设使用crypto-js库
// 密钥必须与加密时完全一致(建议从环境变量读取,避免硬编码)
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
// 验证密钥和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
}
);
// 返回Base64格式的密文避免特殊字符问题
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
} catch (error) {
console.error('加密失败:', error);
throw new Error(`加密错误: ${error.message}`);
}
};
/**
* 解密函数
* @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 };