vue3.2实现AES加密解密,秘钥通过API获取,并混淆秘钥,后端thinkphp
import CryptoJS from "crypto-js";
import axios from "axios";
export const encrypt = async(data: any) => {
let storeKey = sessionStorage.getItem('a')
let storeIv:any = sessionStorage.getItem('i')
// 如果秘钥或 IV 不存在,尝试获取秘钥
if (!storeKey || !storeIv) {
await fetchSecretKey(); // 确保秘钥已被获取
storeKey = sessionStorage.getItem('a'); // 再次获取秘钥
storeIv = sessionStorage.getItem('i'); // 再次获取 IV
}
if (!storeKey || !storeIv) {
throw new Error("秘钥或 IV 不存在.");
}
let secretKey = storeKey.replace('FiedGSe5fg6', '').replace('F//Eset5fGDet', '')
let key = CryptoJS.enc.Base64.parse(secretKey);
let replaceIv = storeIv.replace('DGers', '').replace('HrdReK', '')
let iv = CryptoJS.enc.Utf8.parse(replaceIv)
let srcs = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
let encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString();
};
export const decrypt = async(cipherText: any) => {
let storeKey = sessionStorage.getItem('a')
let storeIv:any = sessionStorage.getItem('i')
// 如果秘钥或 IV 不存在,尝试获取秘钥
if (!storeKey || !storeIv) {
await fetchSecretKey(); // 确保秘钥已被获取
storeKey = sessionStorage.getItem('a'); // 再次获取秘钥
storeIv = sessionStorage.getItem('i'); // 再次获取 IV
}
if (!storeKey || !storeIv) {
throw new Error("秘钥或 IV 不存在.");
}
let secretKey = storeKey.replace('FiedGSe5fg6', '').replace('F//Eset5fGDet', '')
let key = CryptoJS.enc.Base64.parse(secretKey);
let replaceIv = storeIv.replace('DGers', '').replace('HrdReK', '')
let iv = CryptoJS.enc.Utf8.parse(replaceIv)
const decrypted = CryptoJS.AES.decrypt(cipherText, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypted.toString(CryptoJS.enc.Utf8);
};
// 获取秘钥并存储在会话缓存中
export const fetchSecretKey = async () => {
// 检查会话缓存中是否已经有秘钥
const cachedKey = sessionStorage.getItem('a');
if (cachedKey) {
return;
}
try {
// 获取当前时间戳
const timestamp = Date.now();
const nonce = generateNonce(); // 生成随机 nonce
// 临时使用一个默认的签名密钥,可以替换为你后端使用的密钥
const tempSecret = 'defaultSecretKey';
const signature = generateSignature(tempSecret, timestamp, nonce); // 生成签名
// 发送请求获取秘钥,带上签名
const response = await axios.post('/api_getKey', {
timestamp,
nonce,
signature,
});
const rawKey = response.data.aesKey;
// 存储到会话缓存中
sessionStorage.setItem('a', rawKey);
sessionStorage.setItem('i', response.data.iv);
} catch (error) {
console.error('Error fetching secret key:', error);
}
};
// 初始化函数,只有第一次项目打开时才执行获取秘钥的逻辑
export const initializeSecretKey = async () => {
const secretKey = sessionStorage.getItem('a')
if (!secretKey) {
await fetchSecretKey(); // 调用获取秘钥的函数
}
};
// 生成随机字符串作为 nonce
const generateNonce = (): string => {
return Math.random().toString(36).substr(2, 15);
};
// 生成签名
const generateSignature = (secretKey: string, timestamp: number, nonce: string): string => {
const message = `${secretKey}${timestamp}${nonce}`;
return CryptoJS.SHA256(message).toString();
};