Source: encrypt.js

  1. 'use strict';
  2. var crypto = require('crypto');
  3. var pkcs7 = require('pkcs7');
  4. var randomEncodingAESKey = require('./randomEncodingAESKey');
  5. /**
  6. * @module open-service-node-sdk/lib/encrypt
  7. * @author xuyuanxiang <xuyuanxiang@wosai-inc.com> ({@link http://xuyuanxiang.me})
  8. * @description 消息加密算法:
  9. * Base64_Encode(AES_Encrypt[random(16B) + msg_len(4B) + msg + $key])
  10. * @example
  11. * const encrypt = require('open-service-node-sdk/lib/encrypt');
  12. * // 数据加密密钥
  13. * const encodingAESKey = 'KLN4DMkqdDKnUvLQ501oitOHsrZy6VRXadgdNcu3jgd';
  14. * // 应用开发商创建应用获取的appId
  15. * const appId = 'e490e912-4c09-11e7-b114-b2f933d5fe66';
  16. * // 消息明文
  17. * const payload = JSON.stringify({ text: 'hello world' });
  18. * // 加密
  19. * const encoded = encrypt(encodingAESKey, appId, payload);
  20. * @param {String} encodingAESKey - 数据加密密钥
  21. * @param {String} appId - 应用开发商创建应用获取的appId
  22. * @param {String} clearData - 消息明文
  23. * @return {String} 密文
  24. */
  25. module.exports = function encrypt(encodingAESKey, appId, clearData) {
  26. // 密钥,生成规则:Base64_Decode(数据加密密钥 + “=”)
  27. var key = new Buffer(encodingAESKey + '=', 'base64');
  28. // 初始向量大小为16字节,取key前16字节
  29. var iv = key.slice(0, 16);
  30. // AES算法,CBC模式
  31. var encipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  32. encipher.setAutoPadding(false);
  33. // 16字节的随机字符串
  34. var randomStr = randomEncodingAESKey(16);
  35. var before = new Buffer(randomStr);
  36. // 4字节的msg长度,网络字节序
  37. var msgLen = new Buffer(4);
  38. // msg为消息体明文
  39. var msg = new Buffer(clearData);
  40. // 应用开发商创建应用获取的appId
  41. var after = new Buffer(appId);
  42. msgLen.writeInt32BE(msg.byteLength, 0);
  43. // source = random(16B) + msg_len(4B) + msg + appId
  44. var source = Buffer.concat([before, msgLen, msg, after]);
  45. // 数据采用PKCS#7填充后进行加密
  46. var piece1 = encipher.update(pkcs7.pad(source));
  47. var piece2 = encipher.final();
  48. // 对明文消息msg加密处理后的Base64编码
  49. return Buffer.concat([piece1, piece2]).toString('base64');
  50. };