老鬼的博客 来都来啦,那就随便看看吧~
Java和Jquery AES CBC加解密
发布于: 2022-12-11 更新于: 2024-05-07 分类于:  阅读次数: 

一:介绍

1
2
前后台分离,有些数据可能要做加解密处理,下面的方式就是用AES做的加解密,
CBC模式需要加密的密钥和偏移量。

二:html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

<!DOCTYPE html>
<html>

<head>
<meta name="viewport" content="width=device-width" />
<meta charset="UTF-8"/>
<title>AES加解密</title>

<!-- 引入 layui.css -->
<link rel="stylesheet" href="https://static.tohours.com/jren/source/layui-v2.6.8/layui/css/layui.css">
<!-- 定义样式和icon -->
<link rel="stylesheet" href="https://static.tohours.com/jren/source/layui-v2.6.8/layui/css/my.css">
<link rel="stylesheet" href="https://static.tohours.com/jren/source/layui-v2.6.8/layui/css/icon.css">


</head>

<body>

<fieldset class="layui-elem-field layui-field-title my_line" style="margin-top: 20px;">
<legend><span class="l jren"></span>AES前后端加解密(<span style="color:red;">日志查看console</span>)</legend>
</fieldset>

<div class="layui-form-item">
<label class="layui-form-label">字符串</label>
<div class="layui-input-block">
<input type="text" name="title" id="password" required lay-verify="required" placeholder="请输入需要加密的字符串" autocomplete="off" class="layui-input">
</div>
</div>

<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn layui-btn-normal" id="pwSend">后端加密前端解密</button>
<button class="layui-btn layui-btn-warm" id="encodeSend">前端加密后端解密</button>
</div>
</div>

</body>


<script src="https://static.tohours.com/jren/source/layui-v2.6.8/layui/layui.js?v=1"></script>
<script src="https://static.tohours.com/jren/source/layui-v2.6.8/layui/myUtils.js?v=1"></script>
<script src="https://static.tohours.com/jren/2022/0224/vconsole.min.3.2.0.js"></script>
<script src="https://static.tohours.com/salesplus/js/jquery.js" type="text/javascript"></script>
<script src="crypto-js.js" type="text/javascript"></script>

<script>

var vConsole = new VConsole();
var key = 'QQHVb2H6zGfjRrm5';
var iv = "YzFB2CIK3ufEi9mf";

$(function () {
$("#pwSend").click(function () {
var password = $("#password").val();
console.log("前端加密后:" + encrypt(password));
postAjax("/encrypt", {content: password}, function (data) {
console.log(data);
console.log("后端加密,前端解密:")
console.log("后端加密后:" + data.resData);
console.log("解密后:" + decrypt(data.resData, key, iv));


})
})

$("#encodeSend").click(function () {
var encryptStr = encrypt($("#password").val(), key, iv);
postAjax("/decrypt", {content: encryptStr}, function (data) {
console.log(data);
console.log("前端加密,后端解密:")
console.log("加密后:" + encryptStr);
console.log("解密后:" + data.resData);
})
})
})

function postAjax(url, dataToPost, d, type, contentType, async) {
url = 'https://jay.tohours.com/wechatapi/common' + url;
console.log(dataToPost);
$.ajax({
url: url,
cache: false,
async: async == undefined ? true : async,
data: dataToPost,
type: type == undefined ? "POST" : type,
contentType: contentType == undefined ? 'application/x-www-form-urlencoded; charset=UTF-8' : contentType,
success: function (data) {
if (typeof d == "function") {
d(data);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (XMLHttpRequest.status == 403) {
layer.msg("您没有权限访问,请联系管理员!")
} else if (XMLHttpRequest.status == 500) {
layer.msg("服务器内部错误!")
} else if (XMLHttpRequest.status == 404) {
layer.msg("您访问的内容不存在!")
} else {
layer.msg("服务器未知错误!")
}
}
});
};

// 加密
function encrypt(code) {
var _code = CryptoJS.enc.Utf8.parse(code),
_key = CryptoJS.enc.Utf8.parse(key),
_iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted = CryptoJS.AES.encrypt(_code, _key, {
iv: _iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return Base64Encode(encrypted.ciphertext.toString())
}
// 解密
function decrypt(code) {
var _key = CryptoJS.enc.Utf8.parse(key),
_iv = CryptoJS.enc.Utf8.parse(iv);

let word = Base64Decode(code)
let encryptedHexStr = CryptoJS.enc.Hex.parse(word)
let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)

var dec = CryptoJS.AES.decrypt(srcs, _key, {
iv: _iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})

var decStr = CryptoJS.enc.Utf8.stringify(dec);
return decStr;
}

//base64 encode
function Base64Encode(val){
let str = CryptoJS.enc.Utf8.parse(val)
let base64 = CryptoJS.enc.Base64.stringify(str)
return base64;
}

function Base64Decode(val){
let words = CryptoJS.enc.Base64.parse(val)
return words.toString(CryptoJS.enc.Utf8)
}
</script>

</html>

三:java代码

  • pom.xml
1
2
3
4
5
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
  • AesJsUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.tohours.cnTools.utils;

import java.io.UnsupportedEncodingException;
import java.util.Objects;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.springframework.stereotype.Component;

import com.tohours.cnTools.exception.TohoursException;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class AesJsUtils2 {


private static final String ALGORITHMSTR = "AES/CBC/PKCS5Padding";
private static final String KEY = "QQHVb2H6zGfjRrm5";
private static final String IV = "YzFB2CIK3ufEi9mf";

/**
* 加密返回的数据转换成 String 类型
*
* @param content 明文
*/
public static String encrypt(String content) {
String result = parseByte2HexStr(Objects.requireNonNull(
aesCbcEncrypt(content.getBytes(), KEY.getBytes(), IV.getBytes())));
try {
byte[] bytes = result.getBytes("UTF-8");
result = Base64Encoder.encode(bytes);
} catch (UnsupportedEncodingException e) {
log.error("String转byte异常",e);
throw new TohoursException("String转byte异常");
}
return result;
}

/**
* 将解密返回的数据转换成 String 类型
*
* @param content Base64编码的密文
*/
public static String decrypt(String content) {
content = Base64Decoder.decodeStr(content);
return new String(
aesCbcDecrypt(parseHexStr2Byte(content), KEY.getBytes(), IV.getBytes()));
}

private static byte[] aesCbcEncrypt(byte[] content, byte[] keyBytes, byte[] iv) {
try {
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
// 设置模式,编码,后端为PKCS5Padding,对应前端是Pkcs7
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(content);
} catch (Exception e) {
log.error("加密异常:" + e.toString());
}
return null;
}

private static byte[] aesCbcDecrypt(byte[] content, byte[] keyBytes, byte[] iv) {
try {
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(content);
} catch (Exception e) {
log.error("解密失败",e);
}
return null;
}

/**
* 将byte数组转换成16进制String
*/
public static String parseByte2HexStr(byte[] buf) {
StringBuilder sb = new StringBuilder();
for (byte b : buf) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}

/**
* 将16进制String转换为byte数组
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}

public static void main(String[] args) {
String c = "123";
System.out.println(encrypt(c));
System.out.println(decrypt(encrypt(c)));
}



}

  • Controller.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.tohours.cnTools.controller;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.tohours.cnTools.annotation.ParamsNotBlank;
import com.tohours.cnTools.support.TohoursResponse;
import com.tohours.cnTools.support.TohoursResult;
import com.tohours.cnTools.utils.AesJsUtils2;
import com.tohours.cnTools.utils.OSSUtils;
import com.tohours.cnTools.utils.QRCodeUtils;

import lombok.extern.slf4j.Slf4j;

/**
* @desc 通用的操作
* @author RenJie
* @date 2022-04-06
*
*/
@RestController
@RequestMapping("/common")
@SuppressWarnings("rawtypes")
@Slf4j
public class CommonContrller extends BaseController {

/**
* @desc AES JS 加密
* @param content 需要加密的内容
* @return
*/
@RequestMapping(value = "encrypt", method = RequestMethod.POST)
public TohoursResult<Object> encrypt(@ParamsNotBlank(defaultDesc = "内容不能为空") String content) {
String encrypt = AesJsUtils2.encrypt(content);
return TohoursResponse.success(encrypt);
}

/**
* @desc AES JS 解密
* @param content 需要解密的内容
* @return
*/
@RequestMapping(value = "decrypt", method = RequestMethod.POST)
public TohoursResult<Object> decrypt(@ParamsNotBlank(defaultDesc = "内容不能为空") String content) {
String decrypt = AesJsUtils2.decrypt(content);
return TohoursResponse.success(decrypt);
}

}

1.png

*************感谢您的阅读*************