Vue项目 RSA分段加解密

一、引入JSEncrypt

1.安装依赖

npm install jsencrypt

2.在main.js(需要引入的地方)引入

import { JSEncrypt } from 'jsencrypt'

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

二、引入转码方法

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

// 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("");
};

在原有的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字节划分。

链接:https://www.jianshu.com/p/70dc1b5e2a7c

Vue中安装RSA加密可以按照以下步骤进行操作: 1. 首先,使用npm安装jsencrypt库,可以在终端中运行以下命令进行安装: ``` npm install jsencrypt ``` 2. 在Vue项目的main.js文件中引入jsencrypt库,可以在文件的顶部添加以下代码: ```javascript import JSEncrypt from "jsencrypt"; ``` 3. 将JSEncrypt对象配置为Vue的全局变量,可以在main.js文件中添加以下代码: ```javascript Vue.prototype.$jsEncrypt = JSEncrypt; ``` 4. 在需要使用RSA加密的地方,可以通过调用后台接口获取公钥,并使用JSEncrypt对象对密码进行加密。以下是一个示例代码: ```javascript // 获取公钥的方法 export function getPubKey() { // 调用后台接口获取公钥的逻辑 } // 在需要加密的地方调用getPubKey方法获取公钥,并使用JSEncrypt对象对密码进行加密 getPubKey().then(publicKey => { let encryptor = new JSEncrypt(); encryptor.setPublicKey(publicKey); let rsaPassWord = encryptor.encrypt(password); // 对加密后的密码进行后续操作 }); ``` 请注意,以上代码仅为示例,具体的实现方式可能会根据你的项目需求而有所不同。你需要根据实际情况修改代码中的接口地址和逻辑。 #### 引用[.reference_title] - *1* *3* [Vue项目rsa加密](https://blog.csdn.net/weixin_62946736/article/details/122886177)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vuersa加密](https://blog.csdn.net/weixin_44271874/article/details/123586752)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值