crypto.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /**
  2. * 加密模块
  3. */
  4. /*
  5. 加密解密示例
  6. const payCrypto = require('../libs/crypto.js'); // 获取加密服务(注意文件所在相对路径)
  7. let ciphertext = { a:1,b:2 };
  8. let encrypted = payCrypto.aes.encrypt({
  9. data: ciphertext, // 待加密的原文
  10. });
  11. let decrypted = payCrypto.aes.decrypt({
  12. data: encrypted, // 待解密的原文
  13. });
  14. // 最终解密得出 decrypted = { a:1,b:2 }
  15. */
  16. const configCenter = require("uni-config-center");
  17. const config = configCenter({ pluginId: 'uni-pay' }).requireFile('config.js');
  18. const crypto = require("crypto");
  19. var util = {};
  20. util.aes = {};
  21. /**
  22. * aes加密
  23. * @param {Object} data 待加密的原文
  24. * @param {Object} key 密钥,如不传,自动取config
  25. * @param {String} mode 默认为aes192支持64位或64以上密钥 其他可选(aes-256-ecb 兼容java等其他后端语言)
  26. * 调用示例
  27. let encrypted = crypto.aes.encrypt({
  28. mode: "aes192",
  29. data: "", // 待加密的原文
  30. });
  31. */
  32. util.aes.encrypt = function(obj) {
  33. let {
  34. data, // 待加密的原文
  35. key, // 密钥,如不传,自动取config
  36. mode = "aes192",
  37. } = obj;
  38. if (!key) key = config.notifyKey;
  39. if (typeof data === "object") data = JSON.stringify(data);
  40. if (mode === "aes-256-ecb") {
  41. // aes-256-ecb算法
  42. return encryptUseAes256Ecb(data, key);
  43. } else {
  44. return encryptUseAes192(data, key);
  45. }
  46. };
  47. /**
  48. * aes解密
  49. * @param {Object} data 待解密的原文
  50. * @param {Object} key 密钥,如不传,自动取config
  51. * @param {String} mode 默认为aes192支持64位或64以上密钥 其他可选(aes-256-ecb 兼容java等其他后端语言)
  52. * 调用示例
  53. let decrypted = crypto.aes.decrypt({
  54. mode: "aes192",
  55. data: "", // 待解密的原文
  56. });
  57. */
  58. util.aes.decrypt = function(obj) {
  59. let {
  60. data, // 待解密的原文
  61. key, // 密钥,如不传,自动取config
  62. mode = "aes192",
  63. } = obj;
  64. if (typeof data === "undefined") {
  65. throw "待解密原文不能为空";
  66. }
  67. if (!key) key = config.notifyKey;
  68. // 解密
  69. let decrypted;
  70. if (mode === "aes-256-ecb") {
  71. // aes-256-ecb算法
  72. return decryptUseAes256Ecb(data, key);
  73. } else {
  74. return decryptUseAes192(data, key);
  75. }
  76. // decrypted 为解密后的内容,即最开始需要加密的原始数据文本data
  77. return decrypted;
  78. };
  79. util.generateUUID = function() {
  80. // 获取当前时间戳
  81. let timestamp = Date.now().toString(16);
  82. while (timestamp.length < 16) {
  83. timestamp = timestamp + "0";
  84. }
  85. // 生成随机数部分
  86. const randomHex = crypto.randomBytes(10).toString('hex');
  87. // 结合时间戳和随机数,并按照UUID格式排列
  88. const uuid = `${timestamp.slice(0, 8)}-${timestamp.slice(8, 12)}-${randomHex.slice(0, 4)}-${randomHex.slice(4, 8)}-${randomHex.slice(8)}`;
  89. return uuid.toLowerCase();
  90. };
  91. module.exports = util;
  92. // aes192算法 - 加密
  93. function encryptUseAes192(data, key) {
  94. const cipher = crypto.createCipher('aes192', key);
  95. let encrypted = cipher.update(data, 'utf8', 'hex');
  96. encrypted += cipher.final('hex');
  97. // encrypted 为加密后的内容
  98. return encrypted;
  99. }
  100. // aes192算法 - 解密
  101. function decryptUseAes192(data, key) {
  102. // aes192 算法
  103. let decrypted;
  104. try {
  105. const decipher = crypto.createDecipher('aes192', key);
  106. decrypted = decipher.update(data, 'hex', 'utf8');
  107. decrypted += decipher.final('utf8');
  108. try {
  109. decrypted = JSON.parse(decrypted);
  110. } catch (err) {}
  111. } catch (err) {
  112. throw "解密失败";
  113. }
  114. // decrypted 为解密后的内容,即最开始需要加密的原始数据文本data
  115. return decrypted;
  116. }
  117. // aes-256-ecb算法 - 加密
  118. function encryptUseAes256Ecb(data, key) {
  119. let paddedData = Buffer.from(data);
  120. let paddedkey = key;
  121. if (paddedkey.length > 32) {
  122. paddedkey = paddedkey.substring(0, 32);
  123. }
  124. paddedkey = Buffer.from(paddedkey);
  125. const cipher = crypto.createCipheriv('aes-256-ecb', paddedkey, '');
  126. cipher.setAutoPadding(false);
  127. const blockSize = 16; // AES块大小为16字节
  128. const paddingSize = blockSize - (paddedData.length % blockSize);
  129. const paddingBuffer = Buffer.alloc(paddingSize, paddingSize);
  130. paddedData = Buffer.concat([paddedData, paddingBuffer]);
  131. let encrypted = cipher.update(paddedData, null, 'base64');
  132. encrypted += cipher.final('base64');
  133. return encrypted;
  134. }
  135. // aes-256-ecb算法 - 解密
  136. function decryptUseAes256Ecb(data, key) {
  137. let paddedkey = key;
  138. if (paddedkey.length > 32) {
  139. paddedkey = paddedkey.substring(0, 32);
  140. }
  141. paddedkey = Buffer.from(paddedkey);
  142. let decrypted;
  143. try {
  144. const decipher = crypto.createDecipheriv('aes-256-ecb', paddedkey, '');
  145. decipher.setAutoPadding(false);
  146. let decrypted = decipher.update(data, 'base64');
  147. decrypted += decipher.final();
  148. const lastByte = decrypted.charCodeAt(decrypted.length - 1);
  149. const paddingSize = lastByte;
  150. decrypted = decrypted.slice(0, decrypted.length - paddingSize);
  151. try {
  152. decrypted = JSON.parse(decrypted);
  153. } catch (err) {}
  154. return decrypted;
  155. } catch (err) {
  156. throw "解密失败";
  157. }
  158. return decrypted;
  159. }