Vue中使用RSA分段加解密

一、引入JSEncrypt

1.安装依赖   npm install jsencrypt

2.在main.js(需要引入的地方)引入import { JSEncrypt } from 'jsencrypt'

3.前端公钥加密、后台私钥解密、请求来的数据后台公钥加密、前端私钥解密

二、引入转码方法

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

  }

};

三、使用方法

前端给后台传输所以要把byte数组进行base64编码

后台传输来的base64的数据前端解码为byte数组

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

}

base64转btye数组

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 //解密后的数据

}

四、Tip

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容