同步操作将从 宇华/gmsm-java 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
国密算法是我国自主研发的密码算法体系,用于保护我国信息安全。它包括对称密码算法、非对称密码算法和杂凑算法,如SM1、SM2、SM3、SM4、SM7、SM9和祖冲之密码算法等。 本软件主要提供了SM2、SM3、SM4三种算法。
SM2是一种非对称加密算法,基于离散对数实现,常用于数字签名和密钥交换;SM3是一种杂凑算法,用于数据完整性校验和消息认证码,该算法为不可逆的算法;SM4是一种分组密码算法,可用于替代DES/AES等国际密码算法,拥有和AES算法相同的密钥长度和分组长度,均为128比特。
除这三种算法的基本实现外,还提供了针对传输加解密、存储加解密、配置文件加解密三种应用场景的算法实现。
传输加解密:采用SM2+SM3+SM4(CBC)的组合。SM2加密SM4的密钥和向量值;SM4加密要传输的数据;SM3保证数据传输的完整性。整个过程中,SM4的密钥和向量值每次都会发生变化,即实现了“一次一密”。
存储加解密:采用SM3+SM4(CBC)的组合。SM3保证数据的完整性;SM4对数据进行加解密。
配置文件加解密:与存储加解密类似。
本软件对应的jar包已经发布到maven中央仓库,只需要在pom.xml中引入即可:
<!--引入国密加解密组件-->
<dependency>
<groupId>cn.openjava</groupId>
<artifactId>gmsm</artifactId>
<version>2.0.5</version>
</dependency>
在cn.openjava.gmsm.test中提供了测试方法:Test.java,运行后可看到各种算法运算后的值。
SM3摘要:C4B26BA9FB01E8A03884C6CEB3A6CAAE4B78EF8391BB8977E342662A32B04275
SM4-生成密钥:CA4AE6E12B72947BD53C71DCB9A8AF07
SM4-ECB加密:6C090B06707137C725AB3321A5FE6B22
SM4-ECB解密:你好,世界
SM4-生成iv:AA26EA6E61053EF7D5858D67F62DA66D
SM4-CBC加密:86833295EEC0EA65B451D071D1035AAE
SM4-CBC解密:你好,世界
SM2-公钥:046042E11E5AE6AEB8A02EE23F36023B99F3048176CA97B3E6416DEC543C402D2E2FB739C6BAAE8E8D4EC66496072E092D1A6DC42375C00337AF6AA871BDF72A90
SM2-私钥:C42B72B3054D98387D2C1360924C54178C2F379971633F5942746AA7F9EFADB8
SM2-密文:049F955BD2CC44C1450D845DD5720A8096B42D61AA20E378FF41739C4A226E7E81CACE7FD443C5C3F2AD7C18DA9BA3A65DA8BAA8D5F30E19FB92422939EACDA23ED9F3B643E2225BBAA008B93D14C43B82BDF1314B28EB56B1C08B5FB67A1F0DC6469C0304B6857B93C4C7D766372C38
SM2-明文:你好,世界
传输加密:D8E2853ABE1338E10AF080CEA93631A1603BAFFA87C7AE9F7F615F67EB8619B2E82182B388C0827BC8DAFE684FFC03F8C191D549F5565D83B4A661080FA87EC7D0A489DE2F06B6620E786D97389A3339B2A4CFACBDD4F77976BCD46783841D9D83706E1D0B1EAC48B936658D2BC2CA79G04C6A40D212E467CA0831111E7754BA1C5E2CC16C31DED0BBB4969E96B7A203D34EF10327BA981B5F6FBA295DC1A5C65E8FF785D8DBF121248A34071E25F881939C9AD64BECA8EDDD2AD38FC62189D07148BFD5F4B6D07596C7D0887750D819844A0B5FBDC0AD6728210DA6CB550C777ABE8E41CF19A0781EB2454442C94B64B5A
传输解密:你好,世界
传输解密-对象:你好,世界
配置文件加密:09CE1E6685A00B3556A4A49862F9EA9BA98EBBF58EAB0A8364351EACC59751AE5FB877105807AF6C38B7574A02B2341AA775B65781B04671393E495043E925C6A7D29F4BE5E64B48AFBBBBAF0023576EF5809444749A92E8BB4F8A95CB288F4B
配置文件解密:你好,世界
数据库加密:931A4033B0ABB103C741D397D02B5367551C2A444E630FDFF63FD0E8C37A388E53EDC25FACFDC272D8A3642A1B6C57A9886DA072D70D87E4072FC00606B73DA41F969DBF7437A2FFB2ED87CAD4D306685F36EC5D554A15E2A90F61E34F41B836
数据库解密:2
1.SM3
SM3.getDigest(data)
2.SM4生成密钥和向量值
String key = SM4.generateKey();
3.SM4(ECB算法)加密:
SM4.encrypt(data, key);
4.SM4(CBC算法)加密:
SM4.encrypt(data, key, iv);
5.SM4(ECB算法)解密:
SM4.decrypt(data, key);
6.SM4(CBC算法)接i密:
SM4.decrypt(data, key, iv);
7.SM2生成公钥和私钥:
SM2KeyPair sm2Keys = SM2.generateSm2Keys(false);
String publicKey = sm2Keys.getPublicKey();
System.out.println("SM2-公钥:" + publicKey);
String privateKey = sm2Keys.getPrivateKey();
System.out.println("SM2-私钥:" + privateKey);
8.SM2加密和解密:
String encrypt = SM2.encrypt(data, publicKey);
System.out.println("SM2-密文:" + encrypt);
String data2 = SM2.decrypt(encrypt, privateKey);
System.out.println("SM2-明文:" + data2);
9.传输加密和解密:
String encrypt1 = GmTransmissionUtil.encrypt(data, sm2PubKey);
System.out.println("传输加密:" + encrypt1);
CipherObj decrypt1 = GmTransmissionUtil.decrypt(encrypt1, sm2PriKey);
System.out.println("传输解密:" + decrypt1.getCipherText());
System.out.println("传输解密-对象:" + GmTransmissionUtil.decrypt(encrypt1, sm2PriKey, String.class));
注意:不要用此软件默认的sm2的公钥和私钥,不安全!!! 请自行生成公钥和私钥。
传输加解密需要和前台配合使用。前端加解密请访问https://gitee.com/cn-openjava/gmsm-js,二者可相互实现加解密。
10.数据库加解密:
String encrypt3 = GmDBUtil.encrypt(2, sm4Key, ivKey);
System.out.println("数据库加密:" + encrypt3);
Integer decrypt2 = GmDBUtil.decrypt(encrypt3, sm4Key, ivKey, Integer.class);
System.out.println("数据库解密:" + decrypt2);
注意:不要用此软件默认的sm4的密钥和向量值,不安全!!! 请自行生成密钥和向量值。
11.配置文件加解密:
String encrypt2 = GmConfigurationUtil.encrypt(data, sm4Key, ivKey);
System.out.println("配置文件加密:" + encrypt2);
System.out.println("配置文件解密:" + GmConfigurationUtil.decrypt(encrypt2, sm4Key, ivKey));
注意:不要用此软件默认的sm4的密钥和向量值,不安全!!! 请自行生成密钥和向量值。****
############################################################################################### ###############################################################################################
前端对应sm2 非对称加解密 后端地址:https://gitee.com/cn-openjava/gmsm-java 前端地址:https://gitee.com/cn-openjava/gmsm-js 1.yarn.lock 引入工具包
sm-crypto@^0.3.13:
version "0.3.13"
resolved "https://registry.npmmirror.com/sm-crypto/-/sm-crypto-0.3.13.tgz#9615d67f9f2280970c353122e5901ae87d64899a"
integrity sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==
dependencies:
jsbn "^1.1.0"
2.package.json 引入工具包
"sm-crypto": "^0.3.13"
3.公钥和私钥隐藏在.env 文件中
4.request.js 文件中 const isSecret = process.env.VUE_APP_SECRET // 是否加密 可判断用 const { sm2 } = require('sm-crypto') // 引入
请求 // request interceptor service.interceptors.request.use( (config) => { // do something before request is sent
if (store.getters.auth) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
// config.headers['X-Token'] = getToken()
// 自定义请求时携带token信息
config.headers.Authorization = 'Bearer ' + store.getters.auth.access_token
}
if (isSecret && config.method === 'post') {
// console.log("未加密参数:", config.data, config.url);
if (config.data && Object.keys(config.data).length) {
const sign = sm2.doSignature(
JSON.stringify(config.data),
privateKeyWeb,
{
hash: true,
der: true
}
)
const decryptingData = sm2.doEncrypt(
JSON.stringify(config.data),
publicKeyServer,
cipherMode
)
config.data = { sign, decryptingData }
// console.log('加密参数:', config.data)
}
}
return config
}, (error) => { // do something with request error // console.log('error', error) // for debug return Promise.reject(error) } )
返回
service.interceptors.response.use( (response) => { // console.log('接口返回值', response) const { sign, decryptingData } = response.data // 解密验签 if (isSecret && decryptingData) { // 解密 if (typeof decryptingData !== 'object') { let decryptStr = sm2.doDecrypt( decryptingData.slice(2), privateKeyWeb, cipherMode ) // 验签 const ver2 = sm2.doVerifySignature(decryptStr, sign, publicKeyServer, { hash: true, der: true }) decryptStr = JSON.parse(decryptStr)
// 验签结果
if (!ver2) {
reVue
.$confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录。',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(() => {
setTimeout(() => {
reVue.$msgbox.close()
store.commit('ClearGroupId')
store.commit('ClearAuth')
store.commit('CloseWindow')
router.push({ path: '/signin' })
}, 500)
})
.catch(() => {
reVue.$msgbox.close()
})
return
} else {
response.data = decryptStr
}
}
}
// console.log('解密后data值', response.config.url, response.data)
if (response.status === 200) {
// eslint-disable-next-line no-trailing-spaces
// 返回code===20001时token信息失效,清除本地保存的验证信息并跳转到登陆页面。
if (response.data.code === 20000) {
return response.data
} else if (response.data.code === 40100) {
if (response.data.msg === '登录状态已过期') {
reVue
.$confirm(
'登录状态已过期,您可以继续留在该页面,或者重新登录。',
'系统提示',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
)
.then(() => {
setTimeout(() => {
reVue.$msgbox.close()
store.commit('ClearGroupId')
store.commit('ClearAuth')
store.commit('CloseWindow')
router.push({ path: '/signin' })
}, 500)
})
.catch(() => {
reVue.$msgbox.close()
})
return Promise.reject(
new Error('无效的会话,或者会话已过期,请重新登录。')
)
} else {
Message({
showClose: true,
message: response.data.msg || 'Error',
type: 'warning',
duration: 5 * 1000
})
return Promise.reject(new Error(response.data.msg || 'Error'))
}
} else if (response.data.code === 20200) {
Message({
showClose: true,
message: '提示:' + response.data.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(response.data.msg || 'Error'))
} else if (response.data.code === 50000) {
// 超时提醒,次数过多进行拦截
if (messageNum > 0) {
return Promise.reject(new Error(response.statusText || 'Error'))
} else {
messageNum++
Message({
message: '提示:' + response.data.msg || 'Error',
type: 'error',
duration: 5 * 1000
})
setTimeout(() => {
messageNum = 0 // 在消息提示自动关闭后重置 messageNum 为 0
}, 500)
return Promise.reject(new Error(response.statusText || 'Error'))
}
} else {
// console.log('未知返回码 response', response)
return Promise.reject(new Error(response.statusText || 'Error'))
}
} else {
Message({
message: '服务器通讯异常' + response.statusText || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(response.statusText || 'Error'))
}
}, (error) => { // console.log('response err' + error) // for debug Message({ message: error, type: 'error', showClose: true, duration: 5 * 1000 }) return Promise.reject(error) } )
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。