5

RSA加密 - Vue

 3 years ago
source link: https://segmentfault.com/a/1190000040450588
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

RSA加密 - Vue

发布于 8 月 3 日

上一篇博客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

−End−- End -−End−


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK