0
点赞
收藏
分享

微信扫一扫

前端rsa加解密

就是耍帅 2022-02-16 阅读 47
前端
// 加密
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 function isEncrypt(data){
  let flag = true
  if(flag){
    if(Object.prototype.toString.call(data) === '[object Object]'){
      data = encrypt(JSON.stringify(data))
      return data      
    }    
  }else{
    return data
  }
}
export function isDecode(data){
  let flag = true
  if(flag){
    data = decrypt(data)
    data = JSON.parse(decodeURIComponent(data)) 
    return data   
  }else{
    return data
  }

}
这里插入代码片
举报

相关推荐

0 条评论