前台加密,后台解密(2) - Node开发

上篇文章主要就是一个引子,是为了介绍我为什么要想去做前台加密,后台解密的这个功能,也可以说是需求吧。这篇文章开始进入主题。

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:

  1. 创建cipher对象,createCipher()createDecipher();
  2. 更新密码,update(),该方法后两个参数指定输入输出编码;
  3. 输出,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的「前台加密,后台解密」就写到这里了。

【好景不长,填完一个坑,另一坑又来了】