// @ts-nocheck import CryptoJS from 'crypto-js'; // 配置信息 const ENCRYPT_CONFIG = { // RSA公钥 - 与后端保持一致 (更新为正确版本,包含ijT7h) RSA_PUBLIC_KEY: 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==', CLIENT_ID: 'e5cd7e4891bf95d1d19206ce24a7b32e', TENANT_ID: '000000', }; /** * 生成随机AES密钥 * @param {number} length 密钥长度,默认32位 * @returns {string} AES密钥 */ export function generateRandomAESKey(length = 32) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; } /** * AES加密数据 * @param {string} data 待加密的数据 * @param {string} key AES密钥 * @returns {string} 加密后的数据 */ export function encryptWithAES(data, key) { const keyUtf8 = CryptoJS.enc.Utf8.parse(key); const encrypted = CryptoJS.AES.encrypt(data, keyUtf8, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7, }); return encrypted.toString(); } /** * Base64字符串转ArrayBuffer * @param {string} base64 * @returns {ArrayBuffer} */ function base64ToArrayBuffer(base64) { const binaryString = atob(base64); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; } /** * ArrayBuffer转Base64字符串 * @param {ArrayBuffer} buffer * @returns {string} */ function arrayBufferToBase64(buffer) { const bytes = new Uint8Array(buffer); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); } /** * 导入RSA公钥 * @param {string} publicKeyBase64 Base64格式的公钥 * @returns {Promise} */ async function importRSAPublicKey(publicKeyBase64) { try { const keyBuffer = base64ToArrayBuffer(publicKeyBase64); const key = await crypto.subtle.importKey( 'spki', keyBuffer, { name: 'RSA-OAEP', hash: 'SHA-1', }, false, ['encrypt'], ); return key; } catch (error) { console.error('导入RSA公钥失败:', error); throw error; } } /** * RSA加密AES密钥 - 使用Web Crypto API * @param {string} aesKey AES密钥 * @returns {Promise} RSA加密后的AES密钥 */ export async function encryptAESKeyWithRSA(aesKey) { try { // 检查Web Crypto API支持 if (!crypto || !crypto.subtle) { throw new Error('当前环境不支持Web Crypto API'); } // 导入RSA公钥 const publicKey = await importRSAPublicKey(ENCRYPT_CONFIG.RSA_PUBLIC_KEY); // 将AES密钥转为Base64(与custom-login-script.js保持一致) const aesKeyBase64 = btoa(unescape(encodeURIComponent(aesKey))); // 将字符串转为ArrayBuffer const dataBuffer = new TextEncoder().encode(aesKeyBase64); // RSA加密 const encryptedBuffer = await crypto.subtle.encrypt( { name: 'RSA-OAEP', }, publicKey, dataBuffer, ); // 转为Base64字符串 const encryptedBase64 = arrayBufferToBase64(encryptedBuffer); console.log('✅ Web Crypto RSA加密成功,结果长度:', encryptedBase64.length); return encryptedBase64; } catch (error) { console.error('Web Crypto RSA加密失败:', error.message); return null; } } /** * 登录数据加密处理 * @param {Object} loginData 登录数据对象 * @returns {Promise} 包含加密数据和请求头的对象 */ export async function encryptLoginData(loginData) { try { // 1. 生成AES密钥 const aesKey = generateRandomAESKey(32); console.log('🔑 生成AES密钥:', aesKey); // 2. 准备完整的登录数据 const fullLoginData = { tenantId: loginData.tenantId || ENCRYPT_CONFIG.TENANT_ID, username: loginData.username, password: loginData.password, clientId: loginData.clientId || ENCRYPT_CONFIG.CLIENT_ID, grantType: loginData.grantType || 'password', }; console.log('📋 登录数据:', JSON.stringify(fullLoginData, null, 2)); // 3. AES加密登录数据 const encryptedData = encryptWithAES(JSON.stringify(fullLoginData), aesKey); console.log('🔐 AES加密后数据长度:', encryptedData.length); // 4. RSA加密AES密钥 - 异步操作 const encryptedKey = await encryptAESKeyWithRSA(aesKey); if (!encryptedKey) { throw new Error('RSA加密AES密钥失败'); } console.log('🔑 RSA加密后密钥长度:', encryptedKey.length); // 5. 返回加密结果和请求头 return { success: true, encryptedData: encryptedData, headers: { 'Content-Type': 'application/json;charset=utf-8', clientid: ENCRYPT_CONFIG.CLIENT_ID, 'encrypt-key': encryptedKey, 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', isToken: 'false', isEncrypt: 'true', repeatSubmit: 'false', }, }; } catch (error) { console.error('登录数据加密失败:', error); return { success: false, error: error.message, }; } } /** * 获取加密配置 */ export function getEncryptConfig() { return ENCRYPT_CONFIG; }