乐趣区

关于vue.js:RSA加密-Vue

前言

上一篇博客 RSA 加密 – Java 实现了 Java 版的 RSA 公钥加密 - 私钥解密,私钥加密 - 公钥解密,这篇博客实现 Vue 下的加解密,记录两种前后端下加解密的场景:

  • 前端公钥加密 – 后端私钥解密
  • 后端私钥加密 – 前端公钥解密

附上其它链接:
RSA 加密 – Java
RSA 分段加密 – Java
RSA 分段解密 – Vue

前端公钥加密 - 后端私钥解密

这种状况较为简单,是通用的做法

  • 装置jsencrypt

    npm install jsencrypt
  • RSAEncryption.js

    /**
     * 非对称加密 -RSA
     * 前端公钥加密 - 后端私钥解密
     *
     */
    import {JSEncrypt} from 'jsencrypt/lib/JSEncrypt'
    
    // 这里的公钥在 Java 端生成
    const PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaaI4MBywkCjIppZnraqN3pbrcZTq/t0+aMBo8K3pK9BDD6XkM6N2Yfcva7BSFbUWuAcI7piXak0UKn9CElDuhNzUSgQn4IXKxIt3Iva5cV83qYumj+0yRjjLT8Muu1Y1rgBZjY9oBwhVoV+Twg25+UJ+6Q6HM4xTwQQJDoyy4jwIDAQAB';
    
    // 注:失常状况下私钥并不会记录在前端,这里应用私钥解密只是记录私钥解密办法
    const PRIVATE_KEY = 'MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJpojgwHLCQKMimlmetqo3elutxlOr+3T5owGjwrekr0EMPpeQzo3Zh9y9rsFIVtRa4BwjumJdqTRQqf0ISUO6E3NRKBCfghcrEi3ci9rlxXzepi6aP7TJGOMtPwy67VjWuAFmNj2gHCFWhX5PCDbn5Qn7pDoczjFPBBAkOjLLiPAgMBAAECgYBnBBKhG7frY5IMDxwd4Euna767hB4qAlbte+JE+ozgrOzyiDXm0wXk0yjKqm8WhczTRwEbYsImjdKmP/GSQoN1AU7yEzM8j0Jgq46m9ZVrHhu2NpuZpr+XueWnA6FNz6tybBgcCwA4t8dvfbOrvjqhrCu01O1xWIpjronyFBN4IQJBAPGuF58xjXyANnp5YU8NhUQ73tTIveRlOpMXDSYkf9lWG26XIGUIsTe0f5jssiNmYtxG+lUm9LLfZgOLcrVkDZ0CQQCjjrBNMXub49efVTCg+nCGT2QXW2BHg/qs5vu8Y34LUHoD/hoEJ+AOWOdnhpRoYOpBwJAm3Gu4a1VmZGGafp0bAkAdfY3aWhSWtZpwNXF/UPoLCnc1Zc1uGkAchLqRBfEn1w7/3qcQTRA66OaNBYzzLuIvWOXhECDZ1tK+6fw0UCItAkAOLibW6n1fDKf7JnWq30u2OVfiNofoa2bmarhUowOgk3+grP0wcwyX8dlOPnrLeeuVe86DsASe3p9u2zEjJesVAkEAhkLiv4TXrC1QlJl7ghksUfFmdT7M4Zxlzj10ConMgq68HkLdmn2nNLsjhUHGwJe3EqM6aozn4zw/Z7uPIT9Fsw==';
    
    export const RSAENCRY = {
      /**
       * 公钥加密
       * @param val 须要加密的字符串
       * @return string 返回加密后果
       */
      encryptByPublicKey: function (val = '') {if(val === ''){return '';}
          let encryptor = new JSEncrypt() // 新建 JSEncrypt 对象
          encryptor.setPublicKey(PUBLIC_KEY) // 设置公钥
          return encryptor.encrypt(val) // 对须要加密的数据进行加密
      },
      /**
       * 私钥解密
       * @param val
       * @returns {string|false|null|PromiseLike<ArrayBuffer>}
       */
      decryptByPrivateKey: function (val = '') {if(val === ''){return '';}
          let decrypt = new JSEncrypt() // 新建 JSEncrypt 对象
          decrypt.setPrivateKey(PRIVATE_KEY) // 设置私钥
          return decrypt.decrypt(val) // 对须要解密的数据进行解密
      }
    }
  • 验证加解密

    import {RSAENCRY} from "../utils/RSAEncryption"
    
    let data = "RSA encrypt!";
    
    let encryptDataByPublicKey = RSAENCRY.encryptByPublicKey(data);
    console.log("encryptDataByPublicKey:", encryptDataByPublicKey)
    
    let decryptDataByPrivateKey = RSAENCRY.decryptByPrivateKey(encryptDataByPublicKey);
    console.log("decryptDataByPrivateKey:", decryptDataByPrivateKey)
  • 后果如下

    ok,如图所示,曾经实现了惯例的前端公钥加密,后端私钥解密

后端私钥加密 – 前端公钥解密

这种状况有点牵强,起因是不想将私钥记录在前端,所以由后端私钥加密 - 前端公钥来解密,后端私钥加密的内容 RSA 加密 – Java 中有记录,这里不再反复,要实现前端公钥解密须要批改配置文件中的内容

  • node-modules 中复制 jsencrypt,这里我复制到了src/libs 目录下
  • 批改src/libs/jsencrypt/lib/lib/jsbn/rsa.js
1. 批改 RSAKey.prototype.decrypt 中 this.doPrivate(c) 为 this.doPublic(c);
RSAKey.prototype.decrypt = function (ctext) {var c = parseBigInt(ctext, 16);
    var m = this.doPublic(c);
    //var m = this.doPrivate(c);
    if (m == null) {return null;}
    return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
};

2. 批改 pkcs1unpad2 正文代码
function pkcs1unpad2(d, n) {var b = d.toByteArray();
    var i = 0;
    while (i < b.length && b[i] == 0) {++i;}
    // 正文该处代码
    // if (b.length - i != n - 1 || b[i] != 2) {
    //     return null;
    // }
    ++i;
    while (b[i] != 0) {if (++i >= b.length) {return null;}
    }
    var ret = "";
    while (++i < b.length) {var c = b[i] & 255;
        if (c < 128) { // utf-8 decode
            ret += String.fromCharCode(c);
        } else if ((c > 191) && (c < 224)) {ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
            ++i;
        } else {ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
            i += 2;
        }
    }
    return ret;
}
  • RSADecryption.js
/**
 * 非对称加密 -RSA
 * 后端私钥加密 - 前端公钥解密
 */
/**
 * 非对称加密 -RSA
 * 后端私钥加密 - 前端公钥解密
 */
import {JSEncrypt} from '../libs/jsencrypt/lib/JSEncrypt'

const PUBLICKEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaaI4MBywkCjIppZnraqN3pbrcZTq/t0+aMBo8K3pK9BDD6XkM6N2Yfcva7BSFbUWuAcI7piXak0UKn9CElDuhNzUSgQn4IXKxIt3Iva5cV83qYumj+0yRjjLT8Muu1Y1rgBZjY9oBwhVoV+Twg25+UJ+6Q6HM4xTwQQJDoyy4jwIDAQAB';

export const RSADECRY = {
    /**
     * 公钥解密
     * @param secretWord
     * @returns {解密 |string|false|PromiseLike<ArrayBuffer>}
     */
    decryptByPublicKey: function (val = '') {if (val === '') {return '';}
        let encrypt = new JSEncrypt();

        encrypt.setPublicKey(PUBLICKEY);

        // 应用公钥对私钥加密后的数据解密
        return encrypt.decrypt(val);
    }
}
  • 调用后端 encryByPrivateKey 函数生成私钥加密密文
String data = "RSA encrypt!";
String encryDataByPrivateKey = encryptByPrivateKey(data);
System.out.println("encryDataByPrivateKey:" + encryDataByPrivateKey);

后果如下所示:

  • 前端公钥解密调用
import {RSADECRY} from "../utils/RSADecryption"

let decryptData = "AwovsO+xeiFSQe6mN9RRCz3FFlMXdCMcrqbNChsc7PbMfCxSHpKWIHQ2IJ/tw8mFsuX84r7TSVhYXB9ATA7nqWxMnKJgkPu+nFXeXSnApjce0MjFtjLpl9wrklVrOL6L0cmzu3DthC44Opwj5EVWF9tjiH7YdKFVK/Q5HVPKcZk=";
let decryptDataByPublicKey = RSADECRY.decryptByPublicKey(decryptData);
console.log("decryptDataByPublicKey:", decryptDataByPublicKey)

后果如下所示:

参考博客:https://my.oschina.net/lwenhao/blog/4304318

源码

  • GitHub:https://github.com/Maggieq8324/coisini-rsa
  • Gitee:https://gitee.com/maggieq8324/coisini-rsa

$$- End -$$

退出移动版