加密解密前端 后端个人思路记录
* 分段加密
* 问题 : 请求后台传参 需要一个对象,包含中文,同时数据量较大(超过 jsencrypt的限制)
* 解决 :对象转 json串转成base64
* 将base64 分段加密 存储。
* 后台获取到对应的base64加密数据在进行分段解密,最终合并在转json字符串.再将json字符串转对象
前端 安装 jsencrypt
cnpm i jsencrypt
封装长加密工具类
/**
* 分段加密
* 问题 : 请求后台传参 需要一个对象,包含中文,同时数据量较大(超过 jsencrypt的限制)
* 解决 :对象转 json串转成base64
* 将base64 分段加密 存储。
* 后台获取到对应的base64加密数据在进行分段解密,最终合并在转json字符串.再将json字符串转对象
*
*/
//安装 cnpm i jsencrypt or npm i jsencrypt
//引入 JSEncrypt
import {JSEncrypt} from "jsencrypt";
//公钥
const publicKeyDef = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoZVnCtN/WZ8WX76+IzNelc+ZvkJLGQ7L9QGQkMA0iLtjt5jJ8+fzCuP1U6rO50Q67PhM5vzFCglALSFVsqGXNm7hrc++kDNhX5sMA0u0gO4L5LsBp5Rb03EGKDT7EBoHiQONw8eorXSniRMutQerhHKMKq03vpm1UuKHwRcaU/wIDAQAB";
// 加密
/**
* 字符串转base64
* 记录出现的问题
* atob()函数用于将一个Base64编码的字符串解码为二进制数据
* Base64编码字符串只包含A-Z、a-z、0-9、+、/和=这些字符
* 如果字符串在包含其他的特殊字符就会报错
* 需要使用window.encodeURIComponent编码再加密
* @param jsonStr json字符串
* @returns {string}
*/
export function strToBase64(jsonStr) {
// 将JSON字符串编码为UTF-8
// 创建 TextEncoder 对象
const encoder = new TextEncoder();
// 调用 encode() 方法将字符串转换为 UTF-8 字节流
const utf8Bytes = encoder.encode(jsonStr);
// 转base64
let base64 = window.btoa(String.fromCharCode.apply(String, utf8Bytes))
return base64
}
/**
* base64 转 字符串
* @param base64
* @returns {string}
*/
export function base64ToStr(base64) {
// 将 Base64 字符串解码为字节数组
let decodedBytes = new Uint8Array(atob(base64).split('').map(char => char.charCodeAt(0)));
// 将字节数组解码为 UTF-8 编码的字符串
let decodedString = new TextDecoder().decode(decodedBytes);
// 将解码后的字符串转为 JSON 对象
// let jsonObject = JSON.parse(decodedString);
// console.log('base64串转json字符:', jsonObject);
return decodedString
}
/**
* 分段加密
* @param plaintextBase64 base64 明文 (被加密的字符串)
* @param fractionalLength 每段的长度(不要太大,否则会加密失败)
* @param separateSymbol 分隔符号 (后台也要根据对应的分隔符号来分割进行分段解析)
* @returns {string}
*/
export function segmentedEncryption(plaintextBase64, fractionalLength = 10, separateSymbol = "", publicKey = publicKeyDef) {
const encryptedSegments = [];
const encryptor = new JSEncrypt()
for (let i = 0; i < plaintextBase64.length; i += fractionalLength) {
const segment = plaintextBase64.substr(i, fractionalLength);
// console.log('分段', segment);
//设置公钥
encryptor.setPublicKey(publicKey)
//加密
const encryptedSegment = encryptor.encrypt(segment);
// console.log('加密', encryptedSegment);
encryptedSegments.push(encryptedSegment);
}
return encryptedSegments.join(separateSymbol)
}
export function segmentedEncryptionByPlaintext(plaintext, fractionalLength = 10, separateSymbol = "", publicKey = publicKeyDef) {
let base64 = strToBase64(plaintext);
return segmentedEncryption(base64, fractionalLength, separateSymbol, publicKey);
}
使用
<template>
<div>
<h1>HelloWorld</h1>
</div>
</template>
<script>
import {JSEncrypt} from "jsencrypt";
import {segmentedEncryptionByPlaintext,strToBase64} from "@/utils/jesencrypt";
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
},
/*加密测试*/
mounted() {
let testObject = {
"temp_name": "测试测试测试测试",
"freight_sercen_leader_idea_user": [],
"load_un_content_opinion_user": [],
"belong_flow": "1",
"belong_user": "640aeb2f6806cb436813183b",
"modifier": "63f437bcc43815561c7a6895",
"modifierName": "dsdadsdadad",
"mtime": "2023-09-11T03:21:15.939Z",
"flow_sort": "1",
"default_uses": "1",
"def_audit_state": "1",
"def_audit_time": "2880",
"belong_role": "6406e31c3c4381579b8e8b330",
"_idString": "640ad800cc438154f4047d24f",
"originalId": "64535c5aa1c438150e08563da5",
"_id": "6453661ec438150e08563daf",
"creator": "63f437bcc43815561c7a6886",
"role": [
"64csc018f2acsc438150csf5020174e"
],
"departmentCode": "CD0",
"sort": "2",
"name": "管理员",
"colum": "freight_service_admin_sa_list_user",
"user": [
"csccsccscs64250234daac028d6c55ess7ca"
],
}
//转json串
let jsonStr = JSON.stringify(testObject)
//得到密文
let ciphertext = segmentedEncryptionByPlaintext(jsonStr, 10, "_")
//请求后台
let par = {
'data': ciphertext
}
this.$post("/comm/testEncryptionAndDecryption", par)
.then(
(res) => {
console.log('res', res)
}
).catch((error) => {
console.log('error', error)
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
后台springboot
/**
* /comm/testEncryptionAndDecryption
* 解密测试
*
* @param map
* @return
* @throws Exception
*/
@NotTokenMethod
@PostMapping("/testEncryptionAndDecryption")
public ObjectRest encryptionAndDecryption(@RequestBody Map<String, Object> map) {
try {
String s = String.valueOf(map.get("data"));
String[] split = s.split("\\_");
PrivateKey privateKey = CommonUtil.JwtUtils.getPrivateKey("jwt//rsa_private_key.key");
StringBuffer stringBuffer = new StringBuffer();
for (String s1 : split) {
byte[] bytes = Base64.decodeBase64(s1.getBytes());
byte[] encoded = privateKey.getEncoded();
//解密
byte[] decodeStr = decryptByPrivateKey(bytes, encoded);
stringBuffer.append(new String(decodeStr));
}
System.out.println(stringBuffer);
String cipherText = new String(Base64.decodeBase64(stringBuffer.toString()));
System.out.println(cipherText);
return ObjectRest.rest(stringBuffer);
} catch (Exception e) {
e.printStackTrace();
return ObjectRest.error("cz", "c");
}
}
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
打印的效果
解密:{“temp_name”:“测试测试测试测试”,“freight_sercen_leader_idea_user”:[],“load_un_content_opinion_user”:[],“belong_flow”:“1”,“belong_user”:“640aeb2f6806cb436813183b”,“modifier”:“63f437bcc43815561c7a6895”,“modifierName”:“dsdadsdadad”,“mtime”:“2023-09-11T03:21:15.939Z”,“flow_sort”:“1”,“default_uses”:“1”,“def_audit_state”:“1”,“def_audit_time”:“2880”,“belong_role”:“6406e31c3c4381579b8e8b330”,“_idString”:“640ad800cc438154f4047d24f”,“originalId”:“64535c5aa1c438150e08563da5”,“_id”:“6453661ec438150e08563daf”,“creator”:“63f437bcc43815561c7a6886”,“role”:[“64csc018f2acsc438150csf5020174e”],“departmentCode”:“CD0”,“sort”:“2”,“name”:“管理员”,“colum”:“freight_service_admin_sa_list_user”,“user”:[“csccsccscs64250234daac028d6c55ess7ca”]}
ipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
打印的效果
[外链图片转存中...(img-hFjfqlOm-1706088490560)]