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

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

1. Node加密模块

首先要说明的是,这里是使用Node开发,第一步我们可能要考虑的是找个加密模块套用一下就行了。这步其实可以更简单,你都根本不用去找,因为Node原生就集成了crypto 加密模块

由于我们的需求是加密完后还要解密的,所以这里我选择了对称加密算法AES,简单封装成函数如下,便于使用。

// 代码摘自 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使用。

安装方法很简单:

npm install crypto-js --save

具体使用方法还是自行查看官方README,上面有分别介绍前台和后台的使用方法。这里我贴一个AES加密算法的示例供参考。

// 在后台新建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了。

  <script src="/crypto-js.js"></script>
  <script src="/javascripts/crypto-aes.js"></script>

3. 写个简单的示例

前台测试页面如下:

<!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代码如下:

// 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的「前台加密,后台解密」就写到这里了。

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


附:


Comments
Write a Comment