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 };