diff --git a/sgzb-ui/package.json b/sgzb-ui/package.json index 6a071e28..08931ad4 100644 --- a/sgzb-ui/package.json +++ b/sgzb-ui/package.json @@ -56,6 +56,7 @@ "qrcodejs2": "0.0.2", "quill": "1.3.7", "screenfull": "5.0.2", + "sm-crypto": "^0.3.13", "sortablejs": "1.10.2", "uuid": "^9.0.1", "vue": "2.6.12", diff --git a/sgzb-ui/src/utils/request.js b/sgzb-ui/src/utils/request.js index 0c0873c6..58c6db37 100644 --- a/sgzb-ui/src/utils/request.js +++ b/sgzb-ui/src/utils/request.js @@ -6,6 +6,7 @@ import errorCode from '@/utils/errorCode' import { tansParams, blobValidate } from "@/utils/ruoyi"; import cache from '@/plugins/cache' import { saveAs } from 'file-saver' +import { decryptWithSM4, encryptWithSM4, hashWithSM3AndSalt } from '@/utils/sm' let downloadLoadingInstance; // 是否显示重新登录 @@ -22,6 +23,17 @@ const service = axios.create({ // request拦截器 service.interceptors.request.use(config => { + const encryptRequest = false + const checkIntegrity = false + const encryptResponse = false + //入参加密 + config.headers['encryptRequest'] = encryptRequest ? 'true' : 'false' + // 数据完整性校验 + config.headers['checkIntegrity'] = checkIntegrity ? 'true' : 'false' + //回参是否加密 + config.headers['encryptResponse'] = encryptResponse ? 'true' : 'false' + // console.log('🚀 ~ config:', config) + // 是否需要设置 token const isToken = (config.headers || {}).isToken === false // 是否需要防止数据重复提交 @@ -42,6 +54,15 @@ service.interceptors.request.use(config => { data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, time: new Date().getTime() } + let contentType = config.headers['Content-Type'] + // console.log('🚀 ~ contentType:', contentType, requestObj.data) + if (contentType.includes('application/json') && typeof requestObj.data !== 'undefined') { + // 加密数据 + if (encryptRequest) { + console.log(hashWithSM3AndSalt(requestObj.data)); + config.data = encryptWithSM4(requestObj.data+"|"+hashWithSM3AndSalt(requestObj.data)) + } + } const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 const limitSize = 5 * 1024 * 1024; // 限制存放数据5M if (requestSize >= limitSize) { @@ -73,6 +94,10 @@ service.interceptors.request.use(config => { // 响应拦截器 service.interceptors.response.use(res => { + // console.log('🚀 ~ 响应-res:', res) + if (res.headers.encryptresponse && !res.data.hasOwnProperty('code')) { + res.data = JSON.parse(decryptWithSM4(res.data)) + } // 未设置状态码则默认成功状态 const code = res.data.code || 200; // 获取错误信息 diff --git a/sgzb-ui/src/utils/sm.js b/sgzb-ui/src/utils/sm.js new file mode 100644 index 00000000..3189ebd8 --- /dev/null +++ b/sgzb-ui/src/utils/sm.js @@ -0,0 +1,70 @@ +// src/utils/encryption.js +import { sm2, sm3, sm4 } from 'sm-crypto' +import SM4 from 'sm-crypto/src/sm4' + +// 配置项,例如盐值、SM2 公私钥、SM4 密钥 +const SM_CONFIG = { + SALT: '2cc0c5f9f1749f1632efa9f63e902323', // SM3 盐值(16 字节) + SM4_KEY:"78d1295afa99449b99d6f83820e6965c", // SM4 对称加密密钥 + SM4_SALT:"f555adf6c01d0ab0761e626a2dae34a2", + SM2_PUBLIC_KEY: 'your-public-key', // SM2 公钥 + SM2_PRIVATE_KEY: 'your-private-key' // SM2 私钥 +} +// AES 配置 +const AES_CONFIG = { + AES_KEY: 'zhgd@bonus@zhgd@bonus@1234567890', // AES key值 + AES_IV: '1234567812345678' // AES 偏移量 +} + +export function generateUUID() { + // 使用当前时间戳和随机数生成一个 UUID + return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + const r = Math.random() * 16 | 0; // 生成随机数 + const v = c === 'x' ? r : (r & 0x3 | 0x8); // 根据 UUID 规范生成相应的值 + return v.toString(16); // 转换为十六进制 + }); +} + +// SM3 哈希 +export function hashSM3(text) { + // 对数据进行哈希计算 + return sm3(text) +} + +// 使用 SM3 进行哈希并加入盐值 +export function hashWithSM3AndSalt(text) { + // 将文本和盐值拼接在一起 + const textWithSalt = SM_CONFIG.SALT + text + // 使用 SM3 进行哈希 + return hashSM3(textWithSalt) +} + +// SM2 加密 +export function encryptWithSM2(text) { + // SM2 公钥加密 + return sm2.doEncrypt(text, SM_CONFIG.SM2_PUBLIC_KEY) +} + +// SM2 解密 +export function decryptWithSM2(encryptedText) { + // SM2 私钥解密 + return sm2.doDecrypt(encryptedText, SM_CONFIG.SM2_PRIVATE_KEY) +} +/** + * 加密函数 + * @param {string} plainText + * @returns {string} 加密后的密文(Hex 编码格式) + */ +export function encryptWithSM4(plainText) { + return sm4.encrypt(plainText, SM_CONFIG.SM4_KEY,{ mode: 'cbc', padding: 'pkcs#5',iv:SM_CONFIG.SM4_SALT}); +} + +/** + * 解密函数 + * @param {string} cipherText + * @returns {string} 解密后的明文 + */ +export function decryptWithSM4(cipherText){ + return SM4.decrypt(cipherText, SM_CONFIG.SM4_KEY,{ mode: 'cbc', padding: 'pkcs#5' ,iv:SM_CONFIG.SM4_SALT}); +} + diff --git a/sgzb-ui/src/views/newLogin.vue b/sgzb-ui/src/views/newLogin.vue index 3d703bb3..37c54ff6 100644 --- a/sgzb-ui/src/views/newLogin.vue +++ b/sgzb-ui/src/views/newLogin.vue @@ -520,6 +520,7 @@ export default { this.$store .dispatch('Login', this.loginForm) .then(async () => { + this.loading = false localStorage.setItem('notice', true) const username = this.loginForm.username.trim() diff --git a/sgzb-ui/src/views/warehouseManage/warehousing/newTools/index.vue b/sgzb-ui/src/views/warehouseManage/warehousing/newTools/index.vue index c0d65d0b..e9e8e893 100644 --- a/sgzb-ui/src/views/warehouseManage/warehousing/newTools/index.vue +++ b/sgzb-ui/src/views/warehouseManage/warehousing/newTools/index.vue @@ -924,7 +924,7 @@ export default { }, handleExportDialog() { this.download( - 'material/purchaseAccessory/exportWareHousingEntry', + 'material/purchaseMacode/exportWareHousingEntry', { taskId: this.query.taskId, },