上篇文章主要就是一个引子,是为了介绍我为什么要想去做前台加密,后台解密的这个功能,也可以说是需求吧。这篇文章开始进入主题。
1. Node加密模块
首先要说明的是,这里是使用Node开发,第一步我们可能要考虑的是找个加密模块套用一下就行了。这步其实可以更简单,你都根本不用去找,因为Node原生就集成了crypto 加密模块。
由于我们的需求是加密完后还要解密的,所以这里我选择了对称加密算法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
// 代码摘自 https://www.liaoxuefeng.com
const crypto = require('crypto');
function aesEncrypt(data, key) {
const cipher = crypto.createCipher('aes192', key);
var crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
}
function aesDecrypt(encrypted, key) {
const decipher = crypto.createDecipher('aes192', key);
var decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
var data = 'Hello, this is a secret message!';
var key = 'Password!';
var encrypted = aesEncrypt(data, key);
var decrypted = aesDecrypt(encrypted, key);
console.log('Plain text: ' + data);
console.log('Encrypted text: ' + encrypted);
console.log('Decrypted text: ' + decrypted);
这里主要使用了3类API:
- 创建cipher对象,
createCipher()
和createDecipher()
; - 更新密码,
update()
,该方法后两个参数指定输入输出编码; - 输出,
final()
2. 前后台加密一致性
问题又来了,Node是自带了crypto加密模块,前台超链接中如果想要使用密文,必须通过后台加密后传参过去,这样不免有些麻烦,也不够灵活。
如果有这么个加密模块,前台后台的API都是一致的,那就更加方便了,别说,还真有,js
的世界里只有你想不到的,没有找不到的。crypto-js就是这样一个模块,前台后台可以调用相同的API使用。
安装方法很简单:
1
npm install crypto-js --save
具体使用方法还是自行查看官方README,上面有分别介绍前台和后台的使用方法。这里我贴一个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
// 在后台新建crypto-aes.js工具模块
var CryptoJS = require('crypto-js');
// var key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; // 32位密钥
// var iv = '1234567812345678'; // 16位
var key = CryptoJS.enc.Utf8.parse('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
var iv = CryptoJS.enc.Utf8.parse('1234567812345678');
function getAes(data){ //加密
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAes(data){//解密
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
var encrypted = getAes('lupeng');
console.log('加密后:' + encrypted);
var data = getDAes(encrypted);
console.log('解密后:' + data);
exports.getAes = getAes;
exports.getDAes = getDAes;
通过引入我们封装好加密模块crypto-aes.js
,在后台中引用就能方便使用getAes
以及getDAes
方法了。
前台页面中引入crypto-js
以及咱们封装好的crypto-aes.js
,就可以使用这两个function
了。
1
2
<script src="/crypto-js.js"></script>
<script src="/javascripts/crypto-aes.js"></script>
3. 写个简单的示例
前台测试页面如下:
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
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>test</h1>
<form action="">
<input type="text" placeholder="test" name='test'>
<button type="submit">提交</button>
<p>code(前台加密): <span id="value"></span></p>
<p>code(后台解密): <span id="returnValue"></span></p>
</form>
</body>
<script src="/jquery/dist/jquery.js"></script>
<script src="/crypto-js.js"></script>
<script src="/javascripts/crypto-aes.js"></script>
<script>
$(function(){
$('button').click(function(e){
e.preventDefault();
var value = $('input[name=test]').val();
var code = getAes(value);
$('#value').text(code);
$.ajax({
url: '/test',
method: 'POST',
data: {
value: value,
code: code
},
success: function(r){
// alert(r);
$('#returnValue').text(r);
}
});
});
})
</script>
</html>
页面很简单不多解释,一个表单提交后异步获取后台解密后的结果,显示到页面上。后台Node代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// express 框架的路由
var express = require('express');
var router = express.Router();
var getAes = require('../libs/util/crypto-aes.js').getAes;
var getDAes = require('../libs/util/crypto-aes.js').getDAes;
// page: index
router.get('/', function(req,res,next){
res.render('test', {
title: 'test page'
});
});
// action: crypto-aes
router.post('/', function(req,res,next){
var value = req.body.value;
var code = req.body.code.toString();
console.log('----------------------: '+code);
var value2 = getDAes(code);
res.send(value2);
});
module.exports = router;
一个Get路由,显示前台页面如下:
页面一个表单,通过异步请求访问后台Post路由,原值为value,前台加密后Code,将这code参数传到后台,后台解密code为value2,传到前台。一个简单测试程序就完成了,Perfect!
好了,Node的「前台加密,后台解密」就写到这里了。
【好景不长,填完一个坑,另一坑又来了】