前言

上一篇文章实现了 Java RSA的分段加解密 ,这里我们介绍在 Vue 项目中如何使用 RSA 分段解密,这里的加解密场景是:

  • 后端私钥分段加密 - 前端公钥分段解密

前端如何使用公钥解密这里不做重复叙述,注重点是分段解密,有需要的参考之前的文章:RSA加密 - Vue



具体实现

  • src/libs/jsencrypt/lib/JSEncrypt.js中添加新的解密方法decryptLong

    /**
    * 分段解密
    * @param string
    * @returns {string|boolean}
    */
     JSEncrypt.prototype.decryptLong = function (string) {
       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;
       }
     };
  • 添加JSEncryptRSAassist.jssrc/libs/jsencrypt/lib/目录下

    /**
     * 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 {
      hexToBytes,
      bytesToHex,
      base64ToArrayBuffer
    }
  • 公钥分段解密RSADecryption.js

    /**
     * 非对称加密 - RSA
     * 后端私钥分段加密 - 前端公钥分段解密
     */
    import { JSEncrypt } from '../libs/jsencrypt/lib/JSEncrypt'
    import { base64ToArrayBuffer } from '../libs/jsencrypt/lib/JSEncryptRSAassist';
    
    const PUBLICKEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaaI4MBywkCjIppZnraqN3pbrcZTq/t0+aMBo8K3pK9BDD6XkM6N2Yfcva7BSFbUWuAcI7piXak0UKn9CElDuhNzUSgQn4IXKxIt3Iva5cV83qYumj+0yRjjLT8Muu1Y1rgBZjY9oBwhVoV+Twg25+UJ+6Q6HM4xTwQQJDoyy4jwIDAQAB';
    
    export const RSADECRY = {
      /**
       * 公钥分段解密
       * @returns {string}
       * @param val
       */
      decryptLongByPublicKey: function (val = '') {
          if(val === ''){
              return '';
          }
          let encrypt = new JSEncrypt()
          encrypt.setPublicKey(PUBLICKEY) // 设置公钥
    
          // 后端使用 URLEncoder 进行编码,前端解密后使用 decodeURIComponent 解码解决中文乱码问题
          let decryptStr = decodeURIComponent(encrypt.decryptLong(base64ToArrayBuffer(val)));
    
          return decryptStr ? decryptStr : val;
      }
    
    }
  • 前端公钥分段解密调用,这里的encryptStrRSA分段加密 - Java 中加密的密文

    console.log("===================")
    let encryptStr = 'LfQFzBVRelSjnohshZlMvTUPsfdaD9t7FEreaAKop5Pf4X33exYMykBS12XCgnMP+GtO08ir5qmsnwVU5iP/lHMlTBSkWiGX16zFV/pmwQF8OY62HrhzXZn0gSu1rIgPKIowQ2W254uYPHDIIxvWJB/dNmeeqrgc5JxDdLVEuZU=';
    let decryptLongByPublicKey = RSADECRY.decryptLongByPublicKey(encryptStr);
    console.log("decryptLongByPublicKey: ", decryptLongByPublicKey);


  • 结果如下:
    在这里插入图片描述

源码

$$- End -$$


梦想是咸鱼
7 声望0 粉丝

万事从未风过耳,一生只是梦游身