diff --git a/package.json b/package.json index fdc8979..98195b8 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "fuse.js": "6.6.2", "js-cookie": "3.0.1", "jsencrypt": "3.3.1", + "crypto-js": "^4.1.1", "nprogress": "0.2.0", "path-browserify": "1.0.1", "path-to-regexp": "6.2.0", @@ -42,6 +43,7 @@ "devDependencies": { "@iconify/json": "^2.2.40", "@intlify/unplugin-vue-i18n": "0.8.2", + "@types/crypto-js": "^4.1.1", "@types/file-saver": "2.0.5", "@types/js-cookie": "3.0.3", "@types/node": "18.14.2", diff --git a/src/api/login.ts b/src/api/login.ts index e85ce3e..2f75ecb 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -19,7 +19,8 @@ export function login(data: LoginData): AxiosPromise { return request({ url: '/auth/login', headers: { - isToken: false + isToken: false, + isEncrypt: true }, method: 'post', data: params diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts new file mode 100644 index 0000000..a3eef8f --- /dev/null +++ b/src/utils/crypto.ts @@ -0,0 +1,45 @@ +import CryptoJS from 'crypto-js'; + +/** + * 随机生成32位的字符串 + * @returns {string} + */ +const generateRandomString = () => { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < 32; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; + +/** + * 随机生成aes 密钥 + * @returns {string} + */ +export const generateAesKey = () => { + return CryptoJS.enc.Utf8.parse(generateRandomString()); +}; + +/** + * 随机生成aes 密钥 + * @returns {string} + */ +export const encryptBase64 = (str: string) => { + return CryptoJS.enc.Base64.stringify(str); +}; + +/** + * 使用密钥对数据进行加密 + * @param message + * @param aesKey + * @returns {string} + */ +export const encryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray) => { + const encrypted = CryptoJS.AES.encrypt(message, aesKey, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }); + return encrypted.toString(); +}; diff --git a/src/utils/jsencrypt.ts b/src/utils/jsencrypt.ts index 18493ad..2d93757 100644 --- a/src/utils/jsencrypt.ts +++ b/src/utils/jsencrypt.ts @@ -2,7 +2,8 @@ import JSEncrypt from 'jsencrypt'; // 密钥对生成 http://web.chacuo.net/netrsakeypair const publicKey = - 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='; + 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='; const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + diff --git a/src/utils/request.ts b/src/utils/request.ts index d5fac4e..74f0d19 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -8,6 +8,8 @@ import { errorCode } from '@/utils/errorCode'; import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; import FileSaver from 'file-saver'; import { getLanguage } from '@/lang'; +import { encryptBase64, encryptWithAes, generateAesKey } from '@/utils/crypto'; +import { encrypt } from '@/utils/jsencrypt'; let downloadLoadingInstance: LoadingInstance; // 是否显示重新登录 @@ -29,6 +31,8 @@ service.interceptors.request.use( const isToken = (config.headers || {}).isToken === false; // 是否需要防止数据重复提交 const isRepeatSubmit = (config.headers || {}).repeatSubmit === false; + // 是否需要加密 + const isEncrypt = (config.headers || {}).isEncrypt === 'true'; if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 } @@ -63,6 +67,13 @@ service.interceptors.request.use( } } } + // 当开启参数加密 + if (isEncrypt && (config.method === 'post' || config.method === 'put')) { + // 生成一个 AES 密钥 + const aesKey = generateAesKey(); + config.headers['encrypt-key'] = encrypt(encryptBase64(aesKey)); + config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey); + } // FormData数据去请求头Content-Type if (config.data instanceof FormData) { delete config.headers['Content-Type'];