系统加密服务-页面JS加密
涉及的问题
- 因涉及的页面较多不能一个一个改,只能统一引用,最好使用header引入js的形式
- 能够捕获form表单提交,在提交之前将提交的数据进行加密,并将加密的数据提交,原始数据不提交
- form表单序列化
- AJAX数据加密
- 加密方式选择
- 文件上传对于和上传数据一起的参数数据加密
问题解决
- 对于第一个问题 写统一的JS进行解决做好兼容性,
- 对于form表单提交加密
解决方案: 使用jquery监听form表单的submit方案,如果监听到form提交就将form表单对应输入框的元素进行序列化,序列为JSON数组(因为后台Request接收数组,兼容类似于checkBox重复name)将序列化的JSON进行加密,并将加密的数据插入到表单中,并将加密的输入框元素设置为disabled(这样元素就不会提交了)提交表单就只剩下加密的数据了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$(function () {
//监听form表单提交
$("form").submit(function (data) {
//获取提交的URL
var url = $(this).attr("action");
//检查是否需要提交
if ($.getSubmit()) {
//检查是否需要加密
if ($.isEncrypt(url)) {
//数据加密
$(this).formEncryption();
}
}
});
}); - 对于form表单序列化
解决方案:对于表单序列化要排除一些不需要加密的元素例如file,button,image等,对于checkbox和redio可能存在多个相同的name,要使用JSON数据来接收,用于区分后台接受到“,”分割的字符串springMvc 会自动将request参数数组转换为“,”分割的字符串,但有些很老的代码是不支持的,要兼容底层request区分数组和“,”分割的字符串要使用JSON数组来接收,并将序列化的name值进行保存,用于某些情况下将加密后disable后的元素去掉disabled,并将加密设置为jquery插件的形式使用。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(function ($) {
//需要排除的元素
var excludeInputType = ["file", "button", "submit", "image", "reset"];
$.fn.extend({
//序列化方法
"serializeJSON": function () {
//表单数据
var formData = {};
//加密的元素数组
var disabledKeys = [];
this.find("input,select,textarea").each(function () {
if (!$(this).is(":disabled")) {
var name = $(this).attr("name");
var value = $(this).val();
var valueArray = new Array(value);
var type = $(this).attr("type");
var flag = true;
for (var i = 0; i < excludeInputType.length; i++) {
if (type == excludeInputType[i]) {
flag = false;
return true;
}
}
disabledKeys.push(name);
switch (type) {
case "checkbox":
if (!$(this).is(':checked')) {
return true;
}
break;
case "radio":
if (!$(this).is(':checked')) {
return true;
}
break;
}
//
var v = $.getJsonValue(formData, name);
if (v) {
v.push(value);
valueArray = v;
}
formData = $.putJson(formData, name, valueArray);
}
});
$.setDisableKey(disabledKeys);
formData = $.arrayParameterSerialize(formData);
return formData;
}
});
}) - 对于AJAX数据提交
解决方案:使用 $.ajaxPrefilter 捕获ajax提交,得到提交的数据,并进行解析,加密并将原始数据覆盖为新的数据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$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
//获取ajax数据
var data = options.data;
//获取ajaxurl
var url = options.url;
//是否需要加密
if ($.isEncrypt(url)) {
if (data) {
var parameter = {};
//检查字符串是否是json字符串
if ($.strIsJSON(data)) {
//将json字符串转换为json对象
parameter = JSON.parse(data);
} else {
//对于普通的数据?xxx=1& 形式的数据进行解析转换为json对象
parameter = $.parseParameter(data);
}
//添加时间戳
parameter = $.addTmp(parameter);
//数据加密
data = $.encryptData(parameter);
var dataJson = {};
dataJson = $.putJson(dataJson, $.getEcryptedParameterName(), data);
data = $.jsonToParameter(dataJson);
//将原始数据覆盖为加密的数据
options.data = data;
}
} - 数据加密
解决方案 使用 des形式加密,可以自己定义加密方式,但要保证前后台都能加密解密。
加密最好加上时间戳 用于后台检查是否解密成功(如果解密后没有这个时间戳字段代表解密失败)还可以用于其他的作用,例如检查加密的字符串超时时间。上下是一个文件 不知道怎么回事 makedown 显示不全一个完整的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(function ($) {
var isSubmit_disabled = true;
var disabled_keys = [];
$.ajaxSetup({
contentType: "application/x-www-form-urlencoded;charset=utf-8",
complete: function (xhr, textStatus) {
if (xhr.status == 911) {
layer.msg('当前页面已失效,正在刷新浏览器', {icon: 0, shade: 0.8}, function () {
window.location.href = $.getRootPath();
});
return false;
}
}
});
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
var data = options.data;
var url = options.url;
if ($.isEncrypt(url)) {
if (data) {
var parameter = {};
if ($.strIsJSON(data)) {
parameter = JSON.parse(data);
} else {
parameter = $.parseParameter(data);
}
parameter = $.addTmp(parameter);
data = $.encryptData(parameter);
var dataJson = {};
dataJson = $.putJson(dataJson, $.getEcryptedParameterName(), data);
data = $.jsonToParameter(dataJson);
options.data = data;
}
}
});
$.fn.extend({
formEncryption: function () {
var data = {};
var ecryptedParameterName = $.getEcryptedParameterName();
var url = $(this).attr("action");
if ($.isEncrypt(url)) {
var inputArray = this.serializeJSON();
if (!inputArray[ecryptedParameterName]) {
$(this).disabledForm();
for (var key in inputArray) {
var value = inputArray[key];
data = $.putJson(data, key, value);
}
data = $.addTmp(data);
var encData = $.encryptData(data);
if ($.isNotEmpty(encData)) {
var encDataInput = $("<input type='hidden' name = '" + ecryptedParameterName + "' value='" + encData + "'/>");
this.append(encDataInput);
}
}
}
},
encryptionSubmit: function () {
this.formEncryption();
this.submit();
},
disabledForm: function () {
var disableKeys = $.getDisableKey();
var ecryptedParameterName = $.getEcryptedParameterName();
for (var i = 0; i < disableKeys.length; i++) {
if (disableKeys[i] != ecryptedParameterName) {
$(this).find("[name='" + disableKeys[i] + "']").attr("disabled", "disabled");
}
}
},
enableForm: function () {
var disableKeys = $.getDisableKey();
var ecryptedParameterName = $.getEcryptedParameterName();
$(this).find("[name='" + ecryptedParameterName + "']").remove();
for (var i = 0; i < disableKeys.length; i++) {
$(this).find("[name='" + disableKeys[i] + "']").attr("disabled", false);
}
}
});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
$.extend({
urlDataEncrypt: function (url, extParams) {
var secretKey = $.getSecretKey();
var baseUrl = $.parseUrl(url);
var params = $.parseUrlParameter(url);
params = $.initEncryptParam(params);
if ($.isNotEmpty(extParams) && $.isJson(extParams)) {
$.putJson(params, extParams);
}
var encryptUrl = url;
if ($.isEmpty(secretKey)) {
encryptUrl = baseUrl + "?" + $.jsonToParameter(params);
} else {
var ecryptedData = $.encryptData(params);
params = $.addTmp(params);
encryptUrl = baseUrl + "?" + $.getEcryptedParameterName() + "=" + ecryptedData;
}
return encryptUrl;
},
encryptData: function (data) {
var ecryptedData = "";
if ($.isJson(data)) {
var jsonStr = JSON.stringify(data);
ecryptedData = strEnc(jsonStr, $.getSecretKey());
} else {
if (!data.match("^\{(.+:.+,*){1,}\}$")) {
var params = $.parseParameter(data);
var jsonStr = JSON.stringify(params);
ecryptedData = strEnc(jsonStr, $.getSecretKey());
} else {
var jsonStr = JSON.stringify(jsonData);
ecryptedData = strEnc(jsonStr, $.getSecretKey());
}
}
return ecryptedData;
},
initEncryptParam: function (data) {
if ($.isEmpty(data)) {
data = {};
} else if (!$.isJson(data)) {
data = jQuery.parseJSON(data);
}
data = $.addTmp(data);
return data;
}, isEncrypt: function (url) {
var flag = true;
var secretKey = $.getSecretKey();
if ($.isEmpty(secretKey)) {
flag = false;
} else {
var encryptExclude = $.encryptExcludeUrl();
if (encryptExclude && $.isArray(encryptExclude)) {
for (var i = 0; i <= encryptExclude.length; i++) {
if (encryptExclude[i] == url) {
flag = false;
break;
}
}
}
}
return flag;
}, setSubmit: function (obj) {
isSubmit_disabled = obj;
},
getSubmit: function () {
return isSubmit_disabled;
},
setDisableKey: function (keys) {
if (keys && keys[0] != $.getEcryptedParameterName()) {
disabled_keys = keys;
}
},
getDisableKey: function () {
return disabled_keys;
},
});
})(window.jQuery);