initialˆ
This commit is contained in:
121
reijm-read/src/utils/encryptionUtil.js
Normal file
121
reijm-read/src/utils/encryptionUtil.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import CryptoJS from 'crypto-js';
|
||||
import pako from 'pako';
|
||||
|
||||
const key2 = CryptoJS.enc.Utf8.parse(',Lscj312.;[]sc`1dsajcjc;;wislacx'); // 32字节的密钥
|
||||
const iv2 = CryptoJS.enc.Utf8.parse(',>ew:[7890;,wd[2'); // 16字节的IV
|
||||
|
||||
// 新增PKCS5Padding移除函数(更健壮)
|
||||
function removePadding(data) {
|
||||
if (data.length === 0) return data;
|
||||
|
||||
const paddingLength = data[data.length - 1];
|
||||
|
||||
|
||||
if (data.length < paddingLength) {
|
||||
console.warn("Padding length greater than data length");
|
||||
return data;
|
||||
}
|
||||
|
||||
return data.slice(0, data.length - paddingLength);
|
||||
}
|
||||
|
||||
// 辅助函数:打印ArrayBuffer内容(调试用)
|
||||
function arrayBufferToString(buffer) {
|
||||
return [...new Uint8Array(buffer)].map(b => b.toString(16).padStart(2, '0')).join(' ');
|
||||
}
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
encryptAndCompress(data) {
|
||||
try {
|
||||
// 压缩数据
|
||||
const dataArray = new TextEncoder().encode(data);
|
||||
const compressed = pako.gzip(dataArray);
|
||||
|
||||
// 加密数据
|
||||
const wordArray = CryptoJS.lib.WordArray.create(compressed);
|
||||
const encrypted = CryptoJS.AES.encrypt(wordArray, key2, {
|
||||
iv: iv2,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
});
|
||||
|
||||
return encrypted.toString();
|
||||
} catch (error) {
|
||||
console.error("Encryption error:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
decompressAndDecrypt(encryptedData, key = key2, iv = iv2) {
|
||||
try {
|
||||
if (!encryptedData || encryptedData.length < 16) {
|
||||
throw new Error("Invalid or empty encrypted data");
|
||||
}
|
||||
|
||||
// 确保 Base64 格式正确
|
||||
const properB64Str = encryptedData.trim().replace(/\s+/g, '');
|
||||
if (!/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/.test(properB64Str)) {
|
||||
throw new Error("Invalid Base64 string");
|
||||
}
|
||||
// 解密数据
|
||||
const cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Base64.parse(properB64Str) });
|
||||
const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
|
||||
iv: iv,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
});
|
||||
if (!decrypted || !decrypted.words) {
|
||||
throw new Error("Decryption failed or returned invalid data");
|
||||
}
|
||||
function wordArrayToUint8Array(wordArray) {
|
||||
const byteArray = [];
|
||||
const words = wordArray.words;
|
||||
const sigBytes = wordArray.sigBytes;
|
||||
|
||||
for (let i = 0; i < sigBytes; i++) {
|
||||
byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
||||
}
|
||||
|
||||
return new Uint8Array(byteArray);
|
||||
}
|
||||
const compressedArray = wordArrayToUint8Array(decrypted);
|
||||
const debugHex = [...compressedArray.slice(0, 32)].map(b => b.toString(16).padStart(2, '0')).join(' ');
|
||||
// 移除PKCS7 Padding
|
||||
const decryptedWithoutPadding = removePadding(compressedArray);
|
||||
// 手动验证是否是合法的GZIP格式
|
||||
if (decryptedWithoutPadding.length < 10 ||
|
||||
(decryptedWithoutPadding[0] !== 0x1f || decryptedWithoutPadding[1] !== 0x8b)) {
|
||||
// 调试输出前32字节
|
||||
const debugHexPostPadding = [...decryptedWithoutPadding.slice(0, 32)].map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
return '';
|
||||
}
|
||||
|
||||
// 解压数据
|
||||
let decompressed;
|
||||
try {
|
||||
decompressed = pako.ungzip(decryptedWithoutPadding);
|
||||
} catch (e) {
|
||||
console.error("GZIP decompression failed", e);
|
||||
throw new Error("Failed to decompress data - invalid gzip format");
|
||||
}
|
||||
|
||||
if (!decompressed || decompressed.length === 0) {
|
||||
throw new Error("Empty decompressed data");
|
||||
}
|
||||
|
||||
// 解压成功,返回解压后的文本数据
|
||||
return new TextDecoder().decode(decompressed);
|
||||
} catch (error) {
|
||||
console.error("Decryption error:", error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// 移除PKCS7 Padding的函数
|
||||
removePadding(byteArray) {
|
||||
// 假设是PKCS7 padding,最后一个字节的值即为填充的字节数
|
||||
const paddingLength = byteArray[byteArray.length - 1];
|
||||
return byteArray.slice(0, byteArray.length - paddingLength);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user