加密和解密函数的核心是基于成熟的加密算法(如AES)实现,结合crypto-js
库可以快速实现安全的加解密逻辑。以下是可直接使用的具体实现代码:
加密解密工具函数(完整代码)
// utils/crypto.js
import CryptoJS from 'crypto-js';
// 注意:生产环境中密钥和IV应从后端动态获取,不要硬编码!
// 密钥(AES要求16/24/32字节,这里用16字节示例)
const SECRET_KEY = CryptoJS.enc.Utf8.parse('3f2e1d0c7b6a5948');
// 初始向量(IV,16字节,增强加密安全性)
const IV = CryptoJS.enc.Utf8.parse('0a1b2c3d4e5f6789');
/**
* 加密函数
* @param {any} data - 待加密的数据(对象、字符串等)
* @returns {string} 加密后的Base64字符串
*/
export const encrypt = (data) => {
if (!data) return '';
try {
// 统一将数据转为JSON字符串(支持对象类型)
const dataStr = typeof data === 'string' ? data : JSON.stringify(data);
// 使用AES-CBC模式加密,PKCS7填充
const encrypted = CryptoJS.AES.encrypt(
dataStr,
SECRET_KEY,
{
iv: IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// 返回加密后的Base64字符串
return encrypted.toString();
} catch (error) {
console.error('加密失败:', error);
return '';
}
};
/**
* 解密函数
* @param {string} encryptedStr - 加密后的字符串
* @returns {any} 解密后的数据(还原为原始类型)
*/
export const decrypt = (encryptedStr) => {
if (!encryptedStr) return null;
try {
// 解密操作
const decrypted = CryptoJS.AES.decrypt(
encryptedStr,
SECRET_KEY,
{
iv: IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// 将解密结果转为UTF8字符串
const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
// 尝试还原为JSON对象(如果原始数据是对象)
try {
return JSON.parse(decryptedStr);
} catch {
// 若不是对象则直接返回字符串
return decryptedStr;
}
} catch (error) {
console.error('解密失败:', error);
return null;
}
};
代码说明
核心依赖:使用
crypto-js
库的AES算法,这是前端常用的对称加密方案(加密解密使用同一密钥)。关键参数:
SECRET_KEY
:加密密钥,必须是16/24/32字节(对应128/192/256位加密强度)。IV
:初始向量,16字节,用于避免相同明文加密后产生相同密文,增强安全性。- 模式:采用
CBC
模式(比ECB
更安全,需配合IV使用)。 - 填充:
PKCS7
填充,解决数据长度不是AES块大小(16字节)倍数的问题。
数据处理:
- 加密时:将输入数据(对象/字符串)转为JSON字符串,统一格式后加密。
- 解密时:将解密结果尝试解析为JSON对象,还原原始数据类型(若原始数据是字符串则直接返回)。
安全注意事项
- 密钥(
SECRET_KEY
)和IV绝对不能硬编码在前端代码中,生产环境应通过后端接口动态获取(例如用户登录后返回临时密钥)。 - 密钥应定期轮换,降低泄露风险。
- 敏感数据(如token、用户信息)建议加密存储,普通数据可选择不加密以减少性能损耗。
通过上述函数,可以在Pinia插件中直接调用encrypt()
和decrypt()
,实现状态的加密存储和解密读取。