update 升级 依赖版本并替换废弃依赖 crypto-js

- 替换已废弃的 crypto-js 为 @noble/ciphers@2.4.0(零依赖、经过安全审计),
    重写 src/utils/crypto.ts,密文格式保持 AES-256-ECB/PKCS7Padding + Base64,
    与后端 Hutool AES 完全兼容,后端零改动(已通过 openssl 比对验证)
  - 升级 @wangeditor-next/editor 5.7.16 -> 6.4.1、
    @wangeditor-next/editor-for-vue 5.1.14 -> 6.4.1(版本严格对齐,
    v6 唯一不兼容点为视频对齐 HTML 结构,导入时自动迁移)
  - 升级 vue 3.5.40 -> 3.5.42、element-plus 2.14.3 -> 2.14.5、
    vxe-table 4.20.8 -> 4.21.9、vxe-pc-ui 4.16.22 -> 4.18.9、
    axios 1.18.1 -> 1.20.0、pinia 4.0.2 -> 4.0.3、vue-router 5.2.0 -> 5.3.1、
    @vueuse/core 14.3.0 -> 14.4.0、highlight.js 11.11.1 -> 11.12.0、
    vue-i18n 11.4.8 -> 11.4.10 及 unocss、sass、oxlint 等开发依赖
This commit is contained in:
疯狂的狮子Li 2026-09-10 11:57:00 +08:00
parent a85fa0aee4
commit dd98d6ceac
4 changed files with 1643 additions and 1072 deletions

View File

@ -25,50 +25,50 @@
"@element-plus/icons-vue": "2.3.2", "@element-plus/icons-vue": "2.3.2",
"@highlightjs/vue-plugin": "2.1.2", "@highlightjs/vue-plugin": "2.1.2",
"@iconify/vue": "^5.0.1", "@iconify/vue": "^5.0.1",
"@vueuse/core": "14.3.0", "@noble/ciphers": "^2.4.0",
"@wangeditor-next/editor": "5.7.16", "@vueuse/core": "14.4.0",
"@wangeditor-next/editor-for-vue": "5.1.14", "@wangeditor-next/editor": "6.4.1",
"@wangeditor-next/editor-for-vue": "6.4.1",
"animate.css": "4.1.1", "animate.css": "4.1.1",
"await-to-js": "3.0.0", "await-to-js": "3.0.0",
"axios": "1.18.1", "axios": "1.20.0",
"crypto-js": "4.2.0",
"echarts": "6.1.0", "echarts": "6.1.0",
"element-plus": "2.14.3", "element-plus": "2.14.5",
"highlight.js": "11.11.1", "highlight.js": "11.12.0",
"image-conversion": "2.1.1", "image-conversion": "2.1.1",
"jsencrypt": "3.5.4", "jsencrypt": "3.5.4",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "4.0.2", "pinia": "4.0.3",
"vue": "3.5.40", "vue": "3.5.42",
"vue-cropper": "1.1.4", "vue-cropper": "1.1.4",
"vue-i18n": "11.4.8", "vue-i18n": "11.4.10",
"vue-json-pretty": "2.6.0", "vue-json-pretty": "2.6.0",
"vue-router": "5.2.0", "vue-router": "5.3.1",
"vue-types": "7.0.0", "vue-types": "7.0.0",
"vxe-pc-ui": "4.16.22", "vxe-pc-ui": "4.18.9",
"vxe-table": "4.20.8" "vxe-table": "4.21.9"
}, },
"devDependencies": { "devDependencies": {
"@types/crypto-js": "4.2.2", "@types/crypto-js": "4.2.2",
"@types/node": "^26.1.1", "@types/node": "^26.1.1",
"@types/nprogress": "0.2.3", "@types/nprogress": "0.2.3",
"@unocss/preset-attributify": "66.7.5", "@unocss/preset-attributify": "66.10.1",
"@unocss/preset-wind3": "66.7.5", "@unocss/preset-wind3": "66.10.1",
"@vitejs/plugin-vue": "^6.0.8", "@vitejs/plugin-vue": "^6.0.8",
"@vue/compiler-sfc": "3.5.40", "@vue/compiler-sfc": "3.5.42",
"autoprefixer": "10.5.4", "autoprefixer": "10.5.5",
"oxfmt": "^0.60.0", "oxfmt": "^0.67.0",
"oxlint": "^1.75.0", "oxlint": "^1.82.0",
"sass": "1.102.0", "sass": "1.104.0",
"typescript": "^6.0.3", "typescript": "^6.0.3",
"unocss": "66.7.5", "unocss": "66.10.1",
"unplugin-auto-import": "21.0.0", "unplugin-auto-import": "21.1.0",
"unplugin-vue-components": "32.1.0", "unplugin-vue-components": "32.1.0",
"unplugin-vue-setup-extend-plus": "1.0.1", "unplugin-vue-setup-extend-plus": "1.0.1",
"vite": "^8.1.5", "vite": "^8.2.2",
"vite-plugin-svg-icons-ng": "^1.9.2", "vite-plugin-svg-icons-ng": "^1.9.3",
"vitest": "4.1.10", "vitest": "4.1.11",
"vue-tsc": "^3.3.8" "vue-tsc": "^3.3.11"
}, },
"browserslist": [ "browserslist": [
"Chrome >= 87", "Chrome >= 87",

2603
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
import * as CryptoJSModule from 'crypto-js'; import { ecb } from '@noble/ciphers/aes.js';
const CryptoJS = ('default' in CryptoJSModule ? CryptoJSModule.default : CryptoJSModule) as typeof CryptoJSModule;
/** /**
* 32 * 32
@ -14,41 +12,58 @@ const generateRandomString = (): string => {
.slice(0, 32); .slice(0, 32);
}; };
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const bytesToBase64 = (bytes: Uint8Array): string => {
let binary = '';
for (const byte of bytes) {
binary += String.fromCharCode(byte);
}
return btoa(binary);
};
const base64ToBytes = (str: string): Uint8Array => {
const binary = atob(str);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes;
};
/** /**
* aes * aes
* @returns {string} * @returns {Uint8Array}
*/ */
export const generateAesKey = (): CryptoJSModule.lib.WordArray => { export const generateAesKey = (): Uint8Array => {
return CryptoJS.enc.Utf8.parse(generateRandomString()); return encoder.encode(generateRandomString());
}; };
/** /**
* base64 * base64
* @returns {string} * @returns {string}
*/ */
export const encryptBase64 = (str: CryptoJSModule.lib.WordArray): string => { export const encryptBase64 = (bytes: Uint8Array): string => {
return CryptoJS.enc.Base64.stringify(str); return bytesToBase64(bytes);
}; };
/** /**
* base64 * base64
*/ */
export const decryptBase64 = (str: string) => { export const decryptBase64 = (str: string): Uint8Array => {
return CryptoJS.enc.Base64.parse(str); return base64ToBytes(str);
}; };
/** /**
* 使 * 使 (AES/ECB/PKCS7Padding )
* @param message * @param message
* @param aesKey * @param aesKey
* @returns {string} * @returns {string}
*/ */
export const encryptWithAes = (message: string, aesKey: CryptoJSModule.lib.WordArray): string => { export const encryptWithAes = (message: string, aesKey: Uint8Array): string => {
const encrypted = CryptoJS.AES.encrypt(message, aesKey, { const encrypted = ecb(aesKey).encrypt(encoder.encode(message));
mode: CryptoJS.mode.ECB, return bytesToBase64(encrypted);
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}; };
/** /**
@ -57,10 +72,7 @@ export const encryptWithAes = (message: string, aesKey: CryptoJSModule.lib.WordA
* @param aesKey * @param aesKey
* @returns {string} * @returns {string}
*/ */
export const decryptWithAes = (message: string, aesKey: CryptoJSModule.lib.WordArray): string => { export const decryptWithAes = (message: string, aesKey: Uint8Array): string => {
const decrypted = CryptoJS.AES.decrypt(message, aesKey, { const decrypted = ecb(aesKey).decrypt(base64ToBytes(message));
mode: CryptoJS.mode.ECB, return decoder.decode(decrypted);
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}; };

View File

@ -6,7 +6,7 @@ import createComponents from './components';
import createSvgIconsPlugin from './svg-icon'; import createSvgIconsPlugin from './svg-icon';
import createCompression from './compression'; import createCompression from './compression';
import createSetupExtend from './setup-extend'; import createSetupExtend from './setup-extend';
import { viteCheckTransitionPlugin } from "./check-transition"; import { viteCheckTransitionPlugin } from './check-transition';
export default (viteEnv: any, isBuild = false): [] => { export default (viteEnv: any, isBuild = false): [] => {
const vitePlugins: any = []; const vitePlugins: any = [];