前端统一加密请求到后端,后端过滤器统一解密

简介

前端统一使用AES随机秘钥加密报文,使用RSA加密AES的秘钥,传输key和value给后台,后台在过滤器中统一解密。

前端代码

  1. 封装ajax 从而达到统一处理请求参数。封装后,前端只能使用ccdrpAjax进行后台请求。
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
(function ($) {
$.extend({
urlArgs: function (url) {
var args = {};
var index = url.indexOf('?');
var query = url.substring(index + 1);
var pairs = query.split('&');
for (var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if (pos == -1) {
continue;
} // 如果没找到,就跳过
var name = pairs[i].substr(0, pos); // 获得名称
var value = pairs[i].substr(pos + 1); // 提取value
value = decodeURI(value);
args[name] = value;
}
return args
},
ccdrpAjax: function (options) {
var defaults = {
type: "POST",
dataType: "json",//返回结果的数据类型
async: true,//是否异步
cache: false,//是否缓存
appPath: true,//是否加上项目前缀
// timeout: 1000 * 60 * 6,
data: {},
success: function (data) {
}
};
var opts = $.extend(defaults, options);

if (opts.appPath) {
opts.url = window.servicePath + opts.url;
}

if (opts.type.toUpperCase() == "POST") {
var params = opts.data;
//判断是否为 FormData数据格式。如果是,就把不是文件类型的数据拿出来进行加密传输。
if (params instanceof FormData) {
var dataTemp = {};
// var i = params.entries();
// while(i.next()){
//
// }
for (const [key, value] of params.entries()) {
if (!(value instanceof File)) {
dataTemp[key] = value;
}
}
$.each(dataTemp, function (n, v) {
params.delete(n);
});
var rsaData = $.devilencrypt(JSON.stringify(dataTemp));
opts.data.append("securekey", rsaData.encryptedrsa);
opts.data.append("securevalue", rsaData.encrypted);
} else {
var rsaData = $.devilencrypt(JSON.stringify(params));
opts.data = {securevalue: rsaData.encrypted, securekey: rsaData.encryptedrsa};
}
}

if (opts.type.toUpperCase() == "GET") {
var params = $.urlArgs(opts.url);
var rsaData = $.devilencrypt(JSON.stringify(params));
var indexT = opts.url.indexOf('?');
var newUrl = opts.url.substring(0, indexT);
opts.url = newUrl + '?securevalue=' + encodeURIComponent(rsaData.encrypted) + '&securekey=' + encodeURIComponent(rsaData.encryptedrsa);
}

var _beforeSend = opts.beforeSend;
opts.beforeSend = function (request) {
if (_beforeSend) {
_beforeSend(httpRequest, status);
}
};

var _complete = opts.complete;
opts.complete = function (httpRequest, status) {
if (_complete) {
_complete(httpRequest, status);
}
};
//统一处理异常
opts.error = function (event, request, settings) {
alert("ajax error check callback :" + JSON.stringify(request));
};
var _success = opts.success;
opts.success = function (data, textStatus, httpRequest) {
//统一处理 登录跳转。

if (_success) {
_success(data, textStatus, httpRequest);
}

};
opts.statusCode = {
404: function () {
alert("ajax net error 404");
}, 400: function () {
alert("ajax net error 400");
}, 502: function () {
alert("ajax net error 502");
}, 500: function () {
alert("ajax net error 500");
}, "500.12": function () {
alert("ajax net error 500.12");
}
};

$.ajax(opts);// ajaxAsync

}
});
})(jQuery);

ccdrpAjax 对文件流不进行加密,对get和post都进行了拦截。

  1. 封装前端RSA 加解密和AES解密,我使用的RSAAES 源码。
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
$(function () {
$.extend({
devilencrypt_res: function (word) {
var key = CryptoJS.enc.Utf8.parse("NZKDDAMXuQQp3tK5QoK9tiY9twlR4hq5");
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
},
devilencrypt: function (word) {
var result = {};
var encrypt = new JSEncrypt({default_key_size: 2048});
var pubkey = "-----BEGIN PUBLIC KEY-----" +
"xxx相关RSA公钥xxx" +
"-----END PUBLIC KEY-----";
encrypt.setPublicKey(pubkey);
var key = $.getAesKey();
var encryptedRsa = encrypt.encrypt(key);
result.encryptedrsa = encryptedRsa;
var key = CryptoJS.enc.Utf8.parse(key);
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
result.encrypted = encrypted.toString();
return result;
},
getAesKey: function (len) {
len = len || 32;
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
/****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
var maxPos = $chars.length;
var keyStr = '';
for (i = 0; i < len; i++) {
keyStr += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return keyStr;
},
});
});
  1. ccdrpAjax 使用样例
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
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>系统</title>
</head>

<body class="signin">

<a id="test1">hello world!</a>
<a id="test2">bbbb</a>
<div class="form-group">
<label for="upload_crowd_name" class="col-sm-2 control-label">人群名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="upload_crowd_name" placeholder="请输入人群名称">
</div>
</div>
<div class="form-group">
<label for="upload_crowd_desc" class="col-sm-2 control-label">人群说明</label>
<div class="col-sm-10">
<textarea class="form-control" id="upload_crowd_desc" cols="20" rows="5"></textarea>
</div>
</div>
<div class="form-group">
<label for="crowd_file" class="col-sm-2 control-label">上传文件</label>
<div class="col-sm-10">
<input type="file" accept=".xlsx" id="crowd_file">
</div>
<button id="test3">开始上传</button>
</div>

</body>
<script th:inline="javascript">
//Thymeleaf 模板引擎
var ctx = [[@{/}]];
window.servicePath = ctx;
</script>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/devil.js}"></script>
<script th:src="@{/js/jsencrypt.min.js}"></script>
<script th:src="@{/ajax/remote.js}"></script>
<script type="text/javascript">
$("#test1").click(function () {
$.ccdrpAjax({
contentType: "application/x-www-form-urlencoded; charset=utf-8",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
type: "post",
url: "mobile/api",
data: {
"username": "sls.s",
},
dataType: "json",
success: function (r) {
alert(r.msg);
}
});
});
$("#test2").click(function () {
$.ccdrpAjax({
contentType: "application/x-www-form-urlencoded; charset=utf-8",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
type: "get",
url: "mobile/userApi?username=111&&bb=11",
dataType: "json",
success: function (r) {
alert(r.msg);
}
});
});

$('#test3').click(function () {
//上传文件。
var crowd_name = $.trim($('#upload_crowd_name').val());
var crowd_desc = $.trim($('#upload_crowd_desc').val());
var crowd_file = $('#crowd_file')[0].files[0];

var formData = new FormData();

formData.append("file", $('#crowd_file')[0].files[0]);
formData.append("crowd_name", crowd_name);
formData.append("crowd_desc", crowd_desc);
//或者 testForm为form表单ID
// var form = new FormData(document.getElementById("testForm"));
// var formData = new FormData(form);
$.ccdrpAjax({
url: 'mobile/common/upload',
dataType: 'json',
type: 'POST',
async: false,
data: formData,
processData: false, // 使数据不做处理
contentType: false, // 不要设置Content-Type请求头
success: function (data) {
console.log(data);
if (data.status == 'ok') {
alert('上传成功!');
}
},
error: function (response) {
console.log(response);
}
});
})

</script>
</html>

后台代码

  1. 过滤其中处理的代码
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
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//是否跳过不处理
//if (handleExcludeURL(req, resp)) {
// chain.doFilter(request, response);
// return;
//}
// http信息封装类
Map<String, Object> map = null;
MultiReadHttpServletRequest wrapperRequest = new MultiReadHttpServletRequest(req);
try {
String securevalue = request.getParameter("securevalue");
String securekey = request.getParameter("securekey");
String contentType = req.getContentType();
if (StringUtils.isNotBlank(contentType) && contentType.contains("multipart/form-data")) {
//文件上传请求 *特殊请求
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
MultipartHttpServletRequest multiReq = multipartResolver.resolveMultipart(wrapperRequest);
securevalue = multiReq.getParameter("securevalue");
securekey = multiReq.getParameter("securekey");
}
if (StringUtils.isNotBlank(securekey)) {
String key = DevilRSA.decryptByPrivateKey(securekey);
securevalue = DevilAES.aesDecrypt(securevalue, key);
}
map = JSON.parseObject(securevalue, new TypeReference<Map<String, Object>>() {
});

} catch (Throwable e) {
log.error("过滤器修改paramter异常", e);
}

if (map != null && !map.isEmpty()) {
wrapperRequest.addAllParameters(map);
}
chain.doFilter(wrapperRequest, response);
}
  1. MultipartHttpServletRequest封装http请求,从而达到在拦截器和Controller拿到的数据是解密后的数据,并且使流能够重复使用。
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
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
* @author 林非木
* @create 2019年07月10日 16:49
**/
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private static Logger log = LoggerFactory.getLogger(MultiReadHttpServletRequest.class);

private ByteArrayOutputStream cachedBytes;

private Map<String, String[]> params = new HashMap<>();

public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
this.params.putAll(request.getParameterMap());
}

//重载一个构造方法
public MultiReadHttpServletRequest(HttpServletRequest request, Map<String, Object> extendParams) {
this(request);
addAllParameters(extendParams);//这里将扩展参数写入参数表
}

public void addAllParameters(Map<String, Object> otherParams) {//增加多个参数
for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}

public void addParameter(String name, Object value) {//增加参数
if (value != null) {
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}

@Override
public String[] getParameterValues(String name) {
return params.get(name);
}

@Override
public Map<String, String[]> getParameterMap() {
return params;
}

@Override
public Enumeration<String> getParameterNames() {
return new Vector(params.keySet()).elements();
}

@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}

@Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null) {
cacheInputStream();
}

return new CachedServletInputStream();
}

@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}

private void cacheInputStream() throws IOException {
/* Cache the inputstream in order to read it multiple times. For
* convenience, I use apache.commons IOUtils
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}

/* An inputstream which reads the cached request body */
public class CachedServletInputStream extends ServletInputStream {
private ByteArrayInputStream input;

public CachedServletInputStream() {
/* create a new input stream from the cached request body */
input = new ByteArrayInputStream(cachedBytes.toByteArray());
}

@Override
public int read() throws IOException {
return input.read();
}

//jdk1.8 需要重写的方法
@Override
public boolean isFinished() {
return input.available() == 0;
}

@Override
public boolean isReady() {
return true;
}

@Override
public void setReadListener(ReadListener readListener) {

}
}
}
  1. RSA就使用正常的RSA就好,这里使用的如下
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.IOException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
* 前台RSA加密传输,后台解密
*
* @author 林非木
* @version 2.0
* @date 2018年09月28日 下午3:49
*/
@SuppressWarnings("restriction")
public class DevilRSA {

@SuppressWarnings("unused")
private static Logger log = LoggerFactory.getLogger(DevilRSA.class);

public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";

//字节数组转Base64编码
public static String encryptBASE64(byte[] bytes) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(bytes);
}

//Base64编码转字节数组
public static byte[] decryptBASE64(String base64Key) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
return decoder.decodeBuffer(base64Key);
}

public static final String privKey = "";

public static final String pubKey = "";


/**
* 用私钥对信息生成数字签名
*
* @param data 加密数据
* @param privateKey 私钥
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}

// /**
// * @Description 后端加签,传到前端
// * @Date 18-9-28 下午4:42
// * @Author 林非木
// * @Param [data]
// * @return java.lang.String
// **/
// public static String sign(String data) throws Exception {
// return sign(data.getBytes("UTF-8"),privKey);
// }
//
// /**
// * @Description 后端对前端的数据验签
// * @Date 18-9-28 下午4:42
// * @Author 林非木
// * @Param [data]
// * @return java.lang.String
// **/
// public static boolean verify(String data,String sign) throws Exception{
// return verify(data.getBytes("UTF-8"), pubKey1, sign);
// }
//
// /**
// * @Description 后端加密,传输到前端
// * @Date 18-9-28 下午4:42
// * @Author 林非木
// * @Param [data]
// * @return java.lang.String
// **/
// public static byte[] encryptByPublicKey(String data) throws Exception{
// return encryptByPublicKey(data,pubKey1);
// }

/**
* @return java.lang.String
* @Description 后端对前端的数据解密
* @Date 18-9-28 下午4:42
* @Author 林非木
* @Param [data]
**/
public static String decryptByPrivateKey(String data) throws Exception {
return new String(decryptByPrivateKey(data, privKey), "UTF-8");
}

/**
* 校验数字签名
*
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return 校验成功返回true 失败返回false
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}

public static byte[] decryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}

/**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(String data, String key)
throws Exception {
return decryptByPrivateKey(decryptBASE64(data), key);
}

/**
* 解密<br>
* 用公钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}

/**
* 加密<br>
* 用公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(String data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data.getBytes());
}

/**
* 加密<br>
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}

/**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Key> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return encryptBASE64(key.getEncoded());
}

/**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
Key key = keyMap.get(PUBLIC_KEY);
return encryptBASE64(key.getEncoded());
}

/**
* 初始化密钥
*
* @return
* @throws Exception
*/
public static Map<String, Key> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
@SuppressWarnings({ "rawtypes", "unchecked" })
Map<String, Key> keyMap = new HashMap(2);
keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
return keyMap;
}
}
  1. AES加解密方法
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
import java.math.BigInteger;

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

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sun.misc.BASE64Decoder;

/**
* AES的加密和解密
*
* @author 林非木
*/
@SuppressWarnings("restriction")
public class DevilAES {
private static Logger logger = LoggerFactory.getLogger(DevilAES.class);

//算法
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

private static final String UTF8 = "UTF-8";
/**
* 将byte[]转为各种进制的字符串
*
* @param bytes byte[]
* @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
* @return 转换后的字符串
*/
public static String binary(byte[] bytes, int radix) {
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
}

/**
* base 64 encode
*
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes) {
return Base64.encodeBase64String(bytes);
}

/**
* base 64 decode
*
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
public static byte[] base64Decode(String base64Code) throws Exception {
return StringUtils.isBlank(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);
}
/**
* AES加密
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(UTF8), "AES"));

return cipher.doFinal(content.getBytes(UTF8));
}


/**
* AES加密为base 64 code
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
}

/**
* AES解密
*
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);

Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(UTF8), "AES"));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes, UTF8);
}


/**
* 将base 64 code AES解密
*
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
return StringUtils.isBlank(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
}
  1. 自行生成一对RSA公钥就可以使用了。