Vue中使用RSA分段加解密

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue中使用RSA分段加解密相关的知识,希望对你有一定的参考价值。

参考技术A // Convert a hex string to a byte array  16进制转byte数组

function hexToBytes(hex)

  for (var bytes = [], c = 0; c < hex.length; c += 2)

    bytes.push(parseInt(hex.substr(c, 2), 16));

  return bytes;



// Convert a byte array to a hex string byte数组转16进制

function bytesToHex(bytes)

  for (var hex = [], i = 0; i < bytes.length; i++)

    hex.push((bytes[i] >>> 4).toString(16));

    hex.push((bytes[i] & 0xF).toString(16));

 

  return hex.join("");

;

分段加解密是自己写的方法需要进行十六进制和byte数组进行相互转换(具体为什么我也不清楚,希望有知道的大神,可以为我指点一下)

在原有的JSEncrypt中添加分段加解密的方法

JSEncrypt.prototype.encryptLong2 = 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;

 

;

// utf-8数组转字符串

function utf8ByteToUnicodeStr(utf8Bytes)

  var unicodeStr = "";

  for (var pos = 0; pos < utf8Bytes.length;)

    var flag = utf8Bytes[pos];

    var unicode = 0;

    if ((flag >>> 7) === 0)

      unicodeStr += String.fromCharCode(utf8Bytes[pos]);

      pos += 1;

    else if ((flag & 0xFC) === 0xFC)

      unicode = (utf8Bytes[pos] & 0x3) << 30;

      unicode |= (utf8Bytes[pos + 1] & 0x3F) << 24;

      unicode |= (utf8Bytes[pos + 2] & 0x3F) << 18;

      unicode |= (utf8Bytes[pos + 3] & 0x3F) << 12;

      unicode |= (utf8Bytes[pos + 4] & 0x3F) << 6;

      unicode |= (utf8Bytes[pos + 5] & 0x3F);

      unicodeStr += String.fromCharCode(unicode);

      pos += 6;

    else if ((flag & 0xF8) === 0xF8)

      unicode = (utf8Bytes[pos] & 0x7) << 24;

      unicode |= (utf8Bytes[pos + 1] & 0x3F) << 18;

      unicode |= (utf8Bytes[pos + 2] & 0x3F) << 12;

      unicode |= (utf8Bytes[pos + 3] & 0x3F) << 6;

      unicode |= (utf8Bytes[pos + 4] & 0x3F);

      unicodeStr += String.fromCharCode(unicode);

      pos += 5;

    else if ((flag & 0xF0) === 0xF0)

      unicode = (utf8Bytes[pos] & 0xF) << 18;

      unicode |= (utf8Bytes[pos + 1] & 0x3F) << 12;

      unicode |= (utf8Bytes[pos + 2] & 0x3F) << 6;

      unicode |= (utf8Bytes[pos + 3] & 0x3F);

      unicodeStr += String.fromCharCode(unicode);

      pos += 4;

    else if ((flag & 0xE0) === 0xE0)

      unicode = (utf8Bytes[pos] & 0x1F) << 12;;

      unicode |= (utf8Bytes[pos + 1] & 0x3F) << 6;

      unicode |= (utf8Bytes[pos + 2] & 0x3F);

      unicodeStr += String.fromCharCode(unicode);

      pos += 3;

    else if ((flag & 0xC0) === 0xC0) //110

      unicode = (utf8Bytes[pos] & 0x3F) << 6;

      unicode |= (utf8Bytes[pos + 1] & 0x3F);

      unicodeStr += String.fromCharCode(unicode);

      pos += 2;

    else

      unicodeStr += String.fromCharCode(utf8Bytes[pos]);

      pos += 1;

   

 

  return unicodeStr;



JSEncrypt.prototype.decryptLong2 = function (string)

  var k = this.getKey();

  var MAX_DECRYPT_BLOCK = 128;//分段解密最大长度限制为128字节

  try

    var ct = "";

    var t1;

    var bufTmp;

    var hexTmp;

    var str = bytesToHex(string); //这块可能有些没有必要,因为sting参数已经及转为byte数组

    var buf = hexToBytes(str);

    var inputLen = buf.length;

    //开始长度

    var offSet = 0;

    //结束长度

    var 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;

        console.log('分段' + offSet)

        console.log(hexTmp)

        console.log(t1)

      else

        bufTmp = buf.slice(offSet, inputLen);

        hexTmp = bytesToHex(bufTmp);

        t1 = k.decrypt(hexTmp);

        ct += t1;

        console.log('分段' + offSet)

        console.log(hexTmp)

        console.log(t1)

     

      offSet += MAX_DECRYPT_BLOCK;

      endOffSet += MAX_DECRYPT_BLOCK;

   

    return ct;

  catch (ex)

    return false;

 

;

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);



function base64ToArrayBuffer(base64)

  var binary_string = window.atob(base64);

  var len = binary_string.length;

  var bytes = new Uint8Array(len);

  for (var i = 0; i < len; i++)

    bytes[i] = binary_string.charCodeAt(i);

 

  return bytes;



const $getrsa = function (password)

  let encrypt = new JSEncrypt()

  encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----公钥----END PUBLIC KEY-----') // 公钥

  let getrsadata = arrayBufferToBase64(encrypt.encryptLong2(password)); //将加密的数据转码为base64

  return getrsadata //加密后的数据



const $decrsa = function (passwords)

  let encrypt = new JSEncrypt()

  encrypt.setPrivateKey('-----BEGIN PRIVATE KEY-----私钥-----') // 私钥

  let decrsadata = encrypt.decryptLong2(base64ToArrayBuffer(passwords)) // password要解密的数据 先转为byte数组在进行解码

  return decrsadata //解密后的数据



后台如果进行分段加密请严格使用117字节划分,前端解析请严格使用128字节划分。

以上是关于Vue中使用RSA分段加解密的主要内容,如果未能解决你的问题,请参考以下文章

RSA加解密及分段加解密

python实现RSA加密和签名以及分段加解密的方案

VUE内使用RSA加解密

Vue项目中的RSA加解密

vue axios请求加RSA 公钥加密 私钥解密

jsencrypt实现前端RSA非对称加密解密(vue项目)