加解密
This commit is contained in:
parent
d9f7b944a7
commit
1609e6d9e2
|
|
@ -30,6 +30,7 @@
|
||||||
"pinia-plugin-persistedstate": "^3.2.3",
|
"pinia-plugin-persistedstate": "^3.2.3",
|
||||||
"sass": "^1.32.13",
|
"sass": "^1.32.13",
|
||||||
"sass-loader": "^16.0.3",
|
"sass-loader": "^16.0.3",
|
||||||
|
"sm-crypto": "^0.3.13",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-i18n": "^9.14.1"
|
"vue-i18n": "^9.14.1"
|
||||||
},
|
},
|
||||||
|
|
@ -9462,6 +9463,11 @@
|
||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsbn": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
|
||||||
|
},
|
||||||
"node_modules/jsdom": {
|
"node_modules/jsdom": {
|
||||||
"version": "16.7.0",
|
"version": "16.7.0",
|
||||||
"resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz",
|
||||||
|
|
@ -11815,6 +11821,14 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sm-crypto": {
|
||||||
|
"version": "0.3.13",
|
||||||
|
"resolved": "https://registry.npmmirror.com/sm-crypto/-/sm-crypto-0.3.13.tgz",
|
||||||
|
"integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
|
||||||
|
"dependencies": {
|
||||||
|
"jsbn": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@
|
||||||
"pinia-plugin-persistedstate": "^3.2.3",
|
"pinia-plugin-persistedstate": "^3.2.3",
|
||||||
"sass": "^1.32.13",
|
"sass": "^1.32.13",
|
||||||
"sass-loader": "^16.0.3",
|
"sass-loader": "^16.0.3",
|
||||||
|
"sm-crypto": "^0.3.13",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-i18n": "^9.14.1"
|
"vue-i18n": "^9.14.1"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
import { appLoginAPI, getUserInfoAPI, iwsLoginAPI } from '@/services/index.js'
|
import { appLoginAPI, getUserInfoAPI, iwsLoginAPI, getConfigApi } from '@/services/index.js'
|
||||||
import { useMemberStore } from '@/stores'
|
import { useMemberStore } from '@/stores'
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
const origin = window.location.href
|
const origin = window.location.href
|
||||||
|
|
@ -37,12 +37,13 @@ const loginForm = reactive({
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
console.log('🚀 ~ onMounted ~ origin:', origin)
|
// console.log('🚀 ~ onMounted ~ origin:', origin)
|
||||||
// uni.showToast({
|
// uni.showToast({
|
||||||
// title: origin,
|
// title: origin,
|
||||||
// icon: 'none',
|
// icon: 'none',
|
||||||
// duration: 5000,
|
// duration: 5000,
|
||||||
// })
|
// })
|
||||||
|
getConfig()
|
||||||
if (origin.indexOf('ticket') != -1) {
|
if (origin.indexOf('ticket') != -1) {
|
||||||
try {
|
try {
|
||||||
uni.showLoading({ title: '登录中' })
|
uni.showLoading({ title: '登录中' })
|
||||||
|
|
@ -109,6 +110,14 @@ const onHandleLogin = async () => {
|
||||||
console.log('🚀 ~ onHandleLogin ~ error:', error)
|
console.log('🚀 ~ onHandleLogin ~ error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const getConfig = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getConfigApi()
|
||||||
|
uni.setStorageSync('systemConfig', res.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.log('🚀 ~ getConfig ~ error:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,6 @@ import { onShow,onLoad } from '@dcloudio/uni-app'
|
||||||
const urlPermissions = ref([])
|
const urlPermissions = ref([])
|
||||||
onShow((options) => {
|
onShow((options) => {
|
||||||
urlPermissions.value = uni.getStorageSync('urlPermissions')
|
urlPermissions.value = uni.getStorageSync('urlPermissions')
|
||||||
|
|
||||||
console.log("yyyyyyy",urlPermissions.value)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,3 +38,11 @@ export const iwsLoginAPI = (data) => {
|
||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取系统配置
|
||||||
|
export const getConfigApi = () => {
|
||||||
|
return http({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/auth/getConfig',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// SM 配置
|
||||||
|
export 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 配置
|
||||||
|
export 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); // 转换为十六进制
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import { useMemberStore } from '@/stores'
|
import { useMemberStore } from '@/stores'
|
||||||
|
import { decryptWithSM4, encryptWithSM4, hashWithSM3AndSalt } from './sm'
|
||||||
|
|
||||||
|
const systemConfig = uni.getStorageSync('systemConfig') || {
|
||||||
|
requestConfig: { encryptRequest: false, checkIntegrity: false, encryptResponse: false },
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加拦截器
|
* 添加拦截器
|
||||||
|
|
@ -8,16 +13,13 @@ import { useMemberStore } from '@/stores'
|
||||||
const ENV = process.env.NODE_ENV
|
const ENV = process.env.NODE_ENV
|
||||||
// export const baseURL = ENV === 'development' ? 'http://192.168.0.244:18580' : 'http://192.168.0.244:18580'//测试
|
// export const baseURL = ENV === 'development' ? 'http://192.168.0.244:18580' : 'http://192.168.0.244:18580'//测试
|
||||||
// export const baseURL = ENV === 'development' ? 'http://sgwpdm.ah.sgcc.com.cn/iws/jiju-api/' : 'http://sgwpdm.ah.sgcc.com.cn/iws/jiju-api/'//生产
|
// export const baseURL = ENV === 'development' ? 'http://sgwpdm.ah.sgcc.com.cn/iws/jiju-api/' : 'http://sgwpdm.ah.sgcc.com.cn/iws/jiju-api/'//生产
|
||||||
export const baseURL = ENV === 'development' ? '/api' : '/iws/jiju-api'; // 宏源服务
|
export const baseURL = ENV === 'development' ? '/api' : '/iws/jiju-api' // 宏源服务
|
||||||
// export const baseURL = ENV === 'development' ? 'http://192.168.0.234:18080' : '***'
|
// export const baseURL = ENV === 'development' ? 'http://192.168.0.234:18080' : '***'
|
||||||
// export const baseURL = ENV === 'development' ? 'http://192.168.1.114:18080' : 'http://192.168.1.117:18080'//马
|
// export const baseURL = ENV === 'development' ? 'http://192.168.1.114:18080' : 'http://192.168.1.117:18080'//马
|
||||||
// export const baseURL = ENV === 'development' ? '/api' : '***'
|
// export const baseURL = ENV === 'development' ? '/api' : '***'
|
||||||
|
|
||||||
// **********OCR识别为NVUE文件页面请求URL需要同步配置**********
|
// **********OCR识别为NVUE文件页面请求URL需要同步配置**********
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* httpInterceptor 分别拦截 request 和 uploadFile 请求
|
* httpInterceptor 分别拦截 request 和 uploadFile 请求
|
||||||
*/
|
*/
|
||||||
|
|
@ -38,6 +40,20 @@ const httpInterceptor = {
|
||||||
...options.header,
|
...options.header,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const header = options.header || {}
|
||||||
|
const { encryptRequest = true, checkIntegrity = true, encryptResponse = true } = header
|
||||||
|
|
||||||
|
//入参加密
|
||||||
|
options.header['encryptRequest'] =
|
||||||
|
systemConfig.requestConfig.encryptRequest && encryptRequest ? 'true' : 'false'
|
||||||
|
// 数据完整性校验
|
||||||
|
options.header['checkIntegrity'] =
|
||||||
|
systemConfig.requestConfig.checkIntegrity && checkIntegrity ? 'true' : 'false'
|
||||||
|
//回参是否加密
|
||||||
|
options.header['encryptResponse'] =
|
||||||
|
systemConfig.requestConfig.encryptResponse && encryptResponse ? 'true' : 'false'
|
||||||
|
// console.log('🚀 ~ invoke ~ options:', options)
|
||||||
|
|
||||||
// 4. 增加 token 请求头标识
|
// 4. 增加 token 请求头标识
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
const token = memberStore.token
|
const token = memberStore.token
|
||||||
|
|
@ -45,6 +61,21 @@ const httpInterceptor = {
|
||||||
if (token) {
|
if (token) {
|
||||||
options.header.Authorization = token
|
options.header.Authorization = token
|
||||||
}
|
}
|
||||||
|
// console.log('🚀 ~ invoke ~ 请求拦截:', options)
|
||||||
|
|
||||||
|
if (options.method === 'POST' || options.method === 'PUT') {
|
||||||
|
options.header['content-type'] = 'application/json;charset=utf-8;'
|
||||||
|
let contentType = options.header['content-type']
|
||||||
|
let data =
|
||||||
|
typeof options.data === 'object' ? JSON.stringify(options.data) : options.data
|
||||||
|
if (contentType.includes('application/json') && typeof data !== 'undefined') {
|
||||||
|
// 加密数据
|
||||||
|
if (systemConfig.requestConfig.encryptRequest && encryptRequest) {
|
||||||
|
console.log('加密后-->', hashWithSM3AndSalt(data))
|
||||||
|
options.data = encryptWithSM4(data + '|' + hashWithSM3AndSalt(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +88,11 @@ export const http = (options) => {
|
||||||
uni.request({
|
uni.request({
|
||||||
...options,
|
...options,
|
||||||
success(res) {
|
success(res) {
|
||||||
|
// console.log('🚀 ~ 响应拦截 ~ res:', res)
|
||||||
try {
|
try {
|
||||||
|
if (res.header.encryptresponse == 'true' && res.statusCode === 200) {
|
||||||
|
res.data = JSON.parse(decryptWithSM4(res.data))
|
||||||
|
}
|
||||||
// 1. 判断是否请求成功
|
// 1. 判断是否请求成功
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
if (res.data && res.data.code >= 200 && res.data.code < 300) {
|
if (res.data && res.data.code >= 200 && res.data.code < 300) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
|
||||||
|
|
||||||
|
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
||||||
|
|
||||||
|
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
|
||||||
|
'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
||||||
|
|
||||||
|
const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
|
||||||
|
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
|
||||||
|
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
|
||||||
|
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
|
||||||
|
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
|
||||||
|
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
|
||||||
|
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
|
||||||
|
'UP8iWi1Qw0Y='
|
||||||
|
|
||||||
|
// 加密
|
||||||
|
export function encrypt(txt) {
|
||||||
|
const encryptor = new JSEncrypt()
|
||||||
|
encryptor.setPublicKey(publicKey) // 设置公钥
|
||||||
|
return encryptor.encrypt(txt) // 对数据进行加密
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
export function decrypt(txt) {
|
||||||
|
const encryptor = new JSEncrypt()
|
||||||
|
encryptor.setPrivateKey(privateKey) // 设置私钥
|
||||||
|
return encryptor.decrypt(txt) // 对数据进行解密
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { sm2, sm3, sm4 } from 'sm-crypto'
|
||||||
|
// 配置项,例如盐值、SM2 公私钥、SM4 密钥
|
||||||
|
import { SM_CONFIG } from './configure'
|
||||||
|
import SM4 from 'sm-crypto/src/sm4'
|
||||||
|
|
||||||
|
// 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});
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue