1、以下仅适用于数据长度短,长的话会报错
import { JSEncrypt } from 'jsencrypt' // 公钥 const key = `xxxx` // 私钥 const privateKey = `xxxxsss` // 加密 export function encrypt (msg) { const jsencrypt = new JSEncrypt() jsencrypt.setPublicKey(key) return jsencrypt.encrypt(msg) } // 解密 export function decrypt (msg) { let decrypt = new JSEncrypt() decrypt.setPrivateKey(privateKey) var decryptMsg = decrypt.decrypt(msg) return decryptMsg } export default { encrypt , decrypt }

2、数据长度太长,要分段加密解密
import JSEncrypt from 'jsencrypt' 

// 公钥key
const publicKey = 'xxx'
// // 私钥key
const privateKey = 'xxxsss'

// 加密
export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return arrayBufferToBase64(encryptor.encryptLong(txt)) // 对数据进行加密
}

// 解密
export function decrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decryptLong(base64ToArrayBuffer(txt))// 对数据进行解密
}

// btye数组转base64
function arrayBufferToBase64(buffer) {
  var binary = '';
  var bytes = new Uint8Array(buffer);
  var len = bytes.byteLength;
  for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binary);
}
//加密方法
JSEncrypt.prototype.encryptLong = function (string) {
  var k = this.getKey(); 
  try {
    var ct = "";     //RSA每次加密最大117bytes,需要辅助方法判断字符串截取位置
    //1.获取字符串截取点
    var bytes = new Array();
    bytes.push(0);
    var byteNo = 0;
    var len, c;
    len = string.length;
    var temp = 0;
    for (var i = 0; i < len; i++) {
      c = string.charCodeAt(i);
      if (c >= 0x010000 && c <= 0x10FFFF) {
        byteNo += 4;
      } else if (c >= 0x000800 && c <= 0x00FFFF) {
        byteNo += 3;
      } else if (c >= 0x000080 && c <= 0x0007FF) {
        byteNo += 2;
      } else {
        byteNo += 1;
      }
      if ((byteNo % 117) >= 114 || (byteNo % 117) == 0) {
        if (byteNo - temp >= 114) {
          bytes.push(i);
          temp = byteNo;
        }
      }
    }
    //2.截取字符串并分段加密
    if (bytes.length > 1) {
      for (var i = 0; i < bytes.length - 1; i++) {
        var str;
        if (i == 0) {
          str = string.substring(0, bytes[i + 1] + 1);
        } else {
          str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
        }
        var t1 = k.encrypt(str);
        ct += t1;
      };
      if (bytes[bytes.length - 1] != string.length - 1) {
        var lastStr = string.substring(bytes[bytes.length - 1] + 1);
        ct += k.encrypt(lastStr);
      }
      return hexToBytes(ct);
    }
    var t = k.encrypt(string);
    var y = hexToBytes(t);
    return y;
  } catch (ex) {
    return false;
  }
};

/**
 * 分段解密
 * @param string
 * @returns {string|boolean}
 */
 JSEncrypt.prototype.decryptLong = function (string) {
 //第一种解密方式
  var k = this.getKey();
  //解密长度=key size.hex2b64结果是每字节每两字符,所以直接*2
  var maxLength = ((k.n.bitLength()+7)>>3)*2;
  try {
    var hexString = bytesToHex(string);
    var decryptedString = "";
    var rexStr=".{1," + maxLength  + "}";
    var rex =new RegExp(rexStr, 'g'); 
    var subStrArray = hexString.match(rex);
    if(subStrArray){
      subStrArray.forEach(function (entry) {
        decryptedString += k.decrypt(entry);
      });
      return decryptedString;
    }
  } catch (ex) {
    console.log("RSA分段解密失败", ex)
    return false;
  }
  //第二种解密方式
//   let k = this.getKey();
//  let MAX_DECRYPT_BLOCK = 128;//分段解密最大长度限制为128字节
//     //  ## 标题
//   try {
//       let ct = "";
//       let t1;
//       let bufTmp;
//       let hexTmp;
//       let str = bytesToHex(string);
//       let buf = hexToBytes(str);
//       let inputLen = buf.length;

//       //开始长度
//       let offSet = 0;
//       //结束长度
//       let endOffSet = MAX_DECRYPT_BLOCK;

//       //分段解密
//       while (inputLen - offSet > 0) {
//           if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
//               bufTmp = buf.slice(offSet, endOffSet);
//               hexTmp = bytesToHex(bufTmp);
//               t1 = k.decrypt(hexTmp);
//               ct += t1;
//           } else {
//               bufTmp = buf.slice(offSet, inputLen);
//               hexTmp = bytesToHex(bufTmp);
//               t1 = k.decrypt(hexTmp);
//               ct += t1;
//           }
//           offSet += MAX_DECRYPT_BLOCK;
//           endOffSet += MAX_DECRYPT_BLOCK;
//       }
//       return ct;
//   } catch (ex) {
//       console.log("RSA分段解密失败", ex)
//       return false;
//   }
};


/**
* RSA 分段解密辅助
* @param hex
* @returns {[]}
*/

/**
* 16进制转byte数组
*/
function hexToBytes(hex) {
  let bytes = [];
  for (let c = 0; c < hex.length; c += 2)
      bytes.push(parseInt(hex.substr(c, 2), 16));
  return bytes;
}

/**
* byte数组转16进制
* @param bytes
* @returns {string}
*/
function bytesToHex(bytes) {
  let hex = [];
  for (let i = 0; i < bytes.length; i++) {
      hex.push((bytes[i] >>> 4).toString(16));
      hex.push((bytes[i] & 0xF).toString(16));
  }
  return hex.join("");
}

/**
* base64转btye数组
* @param base64
* @returns {Uint8Array}
*/
function base64ToArrayBuffer(base64) {
  let binary_string = window.atob(base64);
  let len = binary_string.length;
  let bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
      bytes[i] = binary_string.charCodeAt(i);
  }

  return bytes;
}

export default {encrypt,decrypt}

我查阅信息的时候有看到一个方法是下载安装encryptlong,来实现长文本加密解密,但我用的时候报错,没整明白再加上时间紧,故而选择这种方式;

有兴趣的朋友可以研究一下,encryptlong

posted on 2022-11-18 16:48  盐孩儿  阅读(572)  评论(0编辑  收藏  举报