159 lines
4.3 KiB
JavaScript
159 lines
4.3 KiB
JavaScript
|
/**
|
|||
|
* 加密模块
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
加密解密示例
|
|||
|
const payCrypto = require('../libs/crypto.js'); // 获取加密服务(注意文件所在相对路径)
|
|||
|
let ciphertext = { a:1,b:2 };
|
|||
|
let encrypted = payCrypto.aes.encrypt({
|
|||
|
data: ciphertext, // 待加密的原文
|
|||
|
});
|
|||
|
|
|||
|
let decrypted = payCrypto.aes.decrypt({
|
|||
|
data: encrypted, // 待解密的原文
|
|||
|
});
|
|||
|
// 最终解密得出 decrypted = { a:1,b:2 }
|
|||
|
*/
|
|||
|
|
|||
|
const configCenter = require("uni-config-center");
|
|||
|
const config = configCenter({ pluginId: 'uni-pay' }).requireFile('config.js');
|
|||
|
const crypto = require("crypto");
|
|||
|
|
|||
|
var util = {};
|
|||
|
util.aes = {};
|
|||
|
/**
|
|||
|
* aes加密
|
|||
|
* @param {Object} data 待加密的原文
|
|||
|
* @param {Object} key 密钥,如不传,自动取config
|
|||
|
* @param {String} mode 默认为aes192支持64位或64以上密钥 其他可选(aes-256-ecb 兼容java等其他后端语言)
|
|||
|
* 调用示例
|
|||
|
let encrypted = crypto.aes.encrypt({
|
|||
|
mode: "aes192",
|
|||
|
data: "", // 待加密的原文
|
|||
|
});
|
|||
|
*/
|
|||
|
util.aes.encrypt = function(obj) {
|
|||
|
let {
|
|||
|
data, // 待加密的原文
|
|||
|
key, // 密钥,如不传,自动取config
|
|||
|
mode = "aes192",
|
|||
|
} = obj;
|
|||
|
if (!key) key = config.notifyKey;
|
|||
|
if (typeof data === "object") data = JSON.stringify(data);
|
|||
|
if (mode === "aes-256-ecb") {
|
|||
|
// aes-256-ecb算法
|
|||
|
return encryptUseAes256Ecb(data, key);
|
|||
|
} else {
|
|||
|
return encryptUseAes192(data, key);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* aes解密
|
|||
|
* @param {Object} data 待解密的原文
|
|||
|
* @param {Object} key 密钥,如不传,自动取config
|
|||
|
* @param {String} mode 默认为aes192支持64位或64以上密钥 其他可选(aes-256-ecb 兼容java等其他后端语言)
|
|||
|
* 调用示例
|
|||
|
let decrypted = crypto.aes.decrypt({
|
|||
|
mode: "aes192",
|
|||
|
data: "", // 待解密的原文
|
|||
|
});
|
|||
|
*/
|
|||
|
util.aes.decrypt = function(obj) {
|
|||
|
let {
|
|||
|
data, // 待解密的原文
|
|||
|
key, // 密钥,如不传,自动取config
|
|||
|
mode = "aes192",
|
|||
|
} = obj;
|
|||
|
if (typeof data === "undefined") {
|
|||
|
throw "待解密原文不能为空";
|
|||
|
}
|
|||
|
if (!key) key = config.notifyKey;
|
|||
|
// 解密
|
|||
|
let decrypted;
|
|||
|
if (mode === "aes-256-ecb") {
|
|||
|
// aes-256-ecb算法
|
|||
|
return decryptUseAes256Ecb(data, key);
|
|||
|
} else {
|
|||
|
return decryptUseAes192(data, key);
|
|||
|
}
|
|||
|
// decrypted 为解密后的内容,即最开始需要加密的原始数据文本data
|
|||
|
return decrypted;
|
|||
|
};
|
|||
|
|
|||
|
module.exports = util;
|
|||
|
|
|||
|
// aes192算法 - 加密
|
|||
|
function encryptUseAes192(data, key) {
|
|||
|
const cipher = crypto.createCipher('aes192', key);
|
|||
|
let encrypted = cipher.update(data, 'utf8', 'hex');
|
|||
|
encrypted += cipher.final('hex');
|
|||
|
// encrypted 为加密后的内容
|
|||
|
return encrypted;
|
|||
|
}
|
|||
|
|
|||
|
// aes192算法 - 解密
|
|||
|
function decryptUseAes192(data, key) {
|
|||
|
// aes192 算法
|
|||
|
let decrypted;
|
|||
|
try {
|
|||
|
const decipher = crypto.createDecipher('aes192', key);
|
|||
|
decrypted = decipher.update(data, 'hex', 'utf8');
|
|||
|
decrypted += decipher.final('utf8');
|
|||
|
try {
|
|||
|
decrypted = JSON.parse(decrypted);
|
|||
|
} catch (err) {}
|
|||
|
} catch (err) {
|
|||
|
throw "解密失败";
|
|||
|
}
|
|||
|
// decrypted 为解密后的内容,即最开始需要加密的原始数据文本data
|
|||
|
return decrypted;
|
|||
|
}
|
|||
|
|
|||
|
// aes-256-ecb算法 - 加密
|
|||
|
function encryptUseAes256Ecb(data, key) {
|
|||
|
let paddedData = Buffer.from(data);
|
|||
|
let paddedkey = key;
|
|||
|
if (paddedkey.length > 32) {
|
|||
|
paddedkey = paddedkey.substring(0, 32);
|
|||
|
}
|
|||
|
paddedkey = Buffer.from(paddedkey);
|
|||
|
const cipher = crypto.createCipheriv('aes-256-ecb', paddedkey, '');
|
|||
|
cipher.setAutoPadding(false);
|
|||
|
const blockSize = 16; // AES块大小为16字节
|
|||
|
const paddingSize = blockSize - (paddedData.length % blockSize);
|
|||
|
const paddingBuffer = Buffer.alloc(paddingSize, paddingSize);
|
|||
|
paddedData = Buffer.concat([paddedData, paddingBuffer]);
|
|||
|
let encrypted = cipher.update(paddedData, null, 'base64');
|
|||
|
encrypted += cipher.final('base64');
|
|||
|
return encrypted;
|
|||
|
}
|
|||
|
|
|||
|
// aes-256-ecb算法 - 解密
|
|||
|
function decryptUseAes256Ecb(data, key) {
|
|||
|
let paddedkey = key;
|
|||
|
if (paddedkey.length > 32) {
|
|||
|
paddedkey = paddedkey.substring(0, 32);
|
|||
|
}
|
|||
|
paddedkey = Buffer.from(paddedkey);
|
|||
|
let decrypted;
|
|||
|
try {
|
|||
|
const decipher = crypto.createDecipheriv('aes-256-ecb', paddedkey, '');
|
|||
|
decipher.setAutoPadding(false);
|
|||
|
|
|||
|
let decrypted = decipher.update(data, 'base64');
|
|||
|
decrypted += decipher.final();
|
|||
|
|
|||
|
const lastByte = decrypted.charCodeAt(decrypted.length - 1);
|
|||
|
const paddingSize = lastByte;
|
|||
|
decrypted = decrypted.slice(0, decrypted.length - paddingSize);
|
|||
|
try {
|
|||
|
decrypted = JSON.parse(decrypted);
|
|||
|
} catch (err) {}
|
|||
|
return decrypted;
|
|||
|
} catch (err) {
|
|||
|
throw "解密失败";
|
|||
|
}
|
|||
|
return decrypted;
|
|||
|
}
|