Vue与Spring boot基于RSA非对称加密进行前后端交互

当处理大型的系统项目,或者保密性要求高的项目。是要解除一些加密算法的,非对称加密肯定比对称加密更加安全,但是也更消耗性能。这里就展示一下前端使用Vue,后端使用Spring boot的情况下,进行前后端交互的情况。

前端

安装加密插件

cnpm install jsencrypt --save

在main.js中全局绑定加密方法,全局设置公匙

import { JSEncrypt } from 'jsencrypt'



Vue.prototype.$encryptByPublicKey=function(content) {
  let encrypt=new JSEncrypt();
  encrypt.setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCH6+puCfJfAWLwIeAqvffe4Hpdr+2W7CI9p5dgsLhtXKvPx+LWAuyTGspwNlQ9DpBTvQEpgnFXkiUGO9DwElJgekAG7Eb3RGN92WQX2BpzvbnZrDYVZT9bTxkNfUABc2zkSG278ndC6e1/gyrkx7rGkLvlHvZwKxy9YPYJL44sBwIDAQAB")
  return encrypt.encrypt(content);
};

测试代码,加密一个字符串,在新窗口打开,传递到后端

 let data = this.$encryptByPublicKey("14d0b282059a4d52b54deb924cabf9d5");
      data=encodeURIComponent(data);
      window.open("http://localhost:18002/ossserver/api/v1/material/file/secret?key="+data);

后端

RSA工具类,加密、解密、生成公匙密匙、签名、验证

package com.grandtech.oss.common;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class RSACoder {
  public static final String KEY_ALGORITHM = "RSA";
  public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

  private static final String PUBLIC_KEY = "RSAPublicKey";
  private static final String PRIVATE_KEY = "RSAPrivateKey";

  public static byte[] decryptBASE64(String key) {
    return Base64.decodeBase64(key);
  }

  public static String encryptBASE64(byte[] bytes) {
    return Base64.encodeBase64String(bytes);
  }

  /**
   * 用私钥对信息生成数字签名
   *
   * @param data       加密数据
   * @param privateKey 私钥
   * @return
   * @throws Exception
   */
  public static String sign(byte[] data, String privateKey) throws Exception {
    // 解密由base64编码的私钥
    byte[] keyBytes = decryptBASE64(privateKey);
    // 构造PKCS8EncodedKeySpec对象
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    // KEY_ALGORITHM 指定的加密算法
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    // 取私钥匙对象
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 用私钥对信息生成数字签名
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initSign(priKey);
    signature.update(data);
    return encryptBASE64(signature.sign());
  }

  public static PrivateKey strToPrivateKey(String privateKey) throws Exception {
    // 解密由base64编码的私钥
    byte[] keyBytes = decryptBASE64(privateKey);
    // 构造PKCS8EncodedKeySpec对象
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    // KEY_ALGORITHM 指定的加密算法
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    // 取私钥匙对象
    return keyFactory.generatePrivate(pkcs8KeySpec);
  }

  /**
   * 校验数字签名
   *
   * @param data      加密数据
   * @param publicKey 公钥
   * @param sign      数字签名
   * @return 校验成功返回true 失败返回false
   * @throws Exception
   */
  public static boolean verify(byte[] data, String publicKey, String sign)
      throws Exception {
    // 解密由base64编码的公钥
    byte[] keyBytes = decryptBASE64(publicKey);
    // 构造X509EncodedKeySpec对象
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    // KEY_ALGORITHM 指定的加密算法
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    // 取公钥匙对象
    PublicKey pubKey = keyFactory.generatePublic(keySpec);
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(pubKey);
    signature.update(data);
    // 验证签名是否正常
    return signature.verify(decryptBASE64(sign));
  }

  public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{
    // 对密钥解密
    byte[] keyBytes = decryptBASE64(key);
    // 取得私钥
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // 对数据解密
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
  }

  /**
   * 解密
* 用私钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(String data, String key) throws Exception { return decryptByPrivateKey(decryptBASE64(data),key); } /** * 解密
* 用公钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密
* 用公钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(String data, String key) throws Exception { // 对公钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data.getBytes()); } /** * 加密
* 用私钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map keyMap) throws Exception { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密钥 * * @return * @throws Exception */ public static Map initKey() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); Map keyMap = new HashMap(2); keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 return keyMap; } }

生成公匙密匙

  @Test
  public void initKey() {
    try {
      Map keyMap= RSACoder.initKey();
      System.out.println(RSACoder.getPrivateKey(keyMap));
      System.out.println(RSACoder.getPublicKey(keyMap));
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

接口接收传进来的加密后的参数,并解密

  @GetMapping("/file/secret")
  private ResponseEntity downFiles(HttpServletRequest request, HttpServletResponse response) {
    String privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIfr6m4J8l8BYvAh4Cq9997gel2v7ZbsIj2nl2CwuG1cq8/H4tYC7JMaynA2VD0OkFO9ASmCcVeSJQY70PASUmB6QAbsRvdEY33ZZBfYGnO9udmsNhVlP1tPGQ19QAFzbORIbbvyd0Lp7X+DKuTHusaQu+Ue9nArHL1g9gkvjiwHAgMBAAECgYBUBDHOfvuAWl0LzgTApthWvi8lRh/4kFHCBpv9un7lqsjREN9YJkqRy5eisRJ1A1GXUVcsj2L8HGwiZEsMembML7ifPReXVYieXPCOIFuPZWwmlBWh3imeU2YvCrvMjG3wQIIlGpWpqjdPX683DYxUF2wAxSRupZ98lvEctU+1oQJBANKFSUSD8Sz9zXKL9xbn24XHshMvWNIkxONtvyJh8Vf3omFEWPtlw6ekSQSAmOhpk6CLyAq5QMtGdHGWZTA+8K8CQQClSPjyLJSwQHfiMZQ66WrNCWXETOhoT9t10KA2BRVmyFQMrxU0zecmrTORpSKTjRjHAoyfUm6rXbI9QY/2SGApAkEAna0S6WxhcS9Pd6H5mYBjXVnquI/X2N2NUkJazCfLmfVx+6QzeWgJGUDlJ6gh3sFkvvSzCcUjEJ1ejcz1USNzJQJAZJPrKTMHp9kTGomg8dhoLSyyyKkkI5W0rhSt6TFevJTa0H0aIm/JYTe0UcRzLeaGVVOvzqOSxKTXeX8T44JXQQJAdvTiEX9a9mvOC8J3893bENv5pfpCOMQKsjyHeMxoS7wJ6rxwoH0KYNWrycYGmpBEcZUgcz8RQ+oeaLDFicudEw==";
    String id= null;
    try {
      String key=request.getParameter("key");
      id = new String(RSACoder.decryptByPrivateKey(key,privateKey));
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }

正常运行前端代码,后端解密正常

RSA并不适合大量数据的加密

你可能感兴趣的:(前端开发,Spring,boot)