'use strict';
var crypto = require('crypto');
var pkcs7 = require('pkcs7');
var randomEncodingAESKey = require('./randomEncodingAESKey');
/**
* @module open-service-node-sdk/lib/encrypt
* @author xuyuanxiang <xuyuanxiang@wosai-inc.com> ({@link http://xuyuanxiang.me})
* @description 消息加密算法:
* Base64_Encode(AES_Encrypt[random(16B) + msg_len(4B) + msg + $key])
* @example
* const encrypt = require('open-service-node-sdk/lib/encrypt');
* // 数据加密密钥
* const encodingAESKey = 'KLN4DMkqdDKnUvLQ501oitOHsrZy6VRXadgdNcu3jgd';
* // 应用开发商创建应用获取的appId
* const appId = 'e490e912-4c09-11e7-b114-b2f933d5fe66';
* // 消息明文
* const payload = JSON.stringify({ text: 'hello world' });
* // 加密
* const encoded = encrypt(encodingAESKey, appId, payload);
* @param {String} encodingAESKey - 数据加密密钥
* @param {String} appId - 应用开发商创建应用获取的appId
* @param {String} clearData - 消息明文
* @return {String} 密文
*/
module.exports = function encrypt(encodingAESKey, appId, clearData) {
// 密钥,生成规则:Base64_Decode(数据加密密钥 + “=”)
var key = new Buffer(encodingAESKey + '=', 'base64');
// 初始向量大小为16字节,取key前16字节
var iv = key.slice(0, 16);
// AES算法,CBC模式
var encipher = crypto.createCipheriv('aes-256-cbc', key, iv);
encipher.setAutoPadding(false);
// 16字节的随机字符串
var randomStr = randomEncodingAESKey(16);
var before = new Buffer(randomStr);
// 4字节的msg长度,网络字节序
var msgLen = new Buffer(4);
// msg为消息体明文
var msg = new Buffer(clearData);
// 应用开发商创建应用获取的appId
var after = new Buffer(appId);
msgLen.writeInt32BE(msg.byteLength, 0);
// source = random(16B) + msg_len(4B) + msg + appId
var source = Buffer.concat([before, msgLen, msg, after]);
// 数据采用PKCS#7填充后进行加密
var piece1 = encipher.update(pkcs7.pad(source));
var piece2 = encipher.final();
// 对明文消息msg加密处理后的Base64编码
return Buffer.concat([piece1, piece2]).toString('base64');
};