SpringBoot整合AES+RSA加密(含前端代码)

作者 : admin 本文共33830个字,预计阅读时间需要85分钟 发布时间: 2024-06-17 共1人阅读

目录

非对称加密和对称加密

RSA和AES简介

混合加密原因:

一、RSA工具类

二、AES工具类

三、解密工具类

四、自定义注解

五、aes加密实体类

六、加密的请求参数

七、这里使用拦截器解密

八、可以修改请求参数的request

九、RSA工具类

十、前端加密需要用到的js

十一、前端拦截器对请求统一加密

十二、为什么使用拦截器不使用aop

总结

非对称加密和对称加密

非对称加密

非对称加密算法是一种密钥的保密方法。非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。

公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

对称加密

加密秘钥和解密秘钥是一样,当你的密钥被别人知道后,就没有秘密可言了

AES 是对称加密算法,优点:加密速度快;缺点:如果秘钥丢失,就容易解密密文,安全性相对比较差

RSA 是非对称加密算法 , 优点:安全 ;缺点:加密速度慢


RSA和AES简介

RSA
加密机制:属于非对称加密,公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,且一一对应。比如:A拥有公钥,B拥有公钥和私钥。A将数据通过公钥进行加密后,发送密文给B,B可以通过私钥进行解密。
AES
加密机制:属于对称加密,就是说,A用密钥对数据进行AES加密后,B用同样的密钥对密文进行AES解密。


加密思路

1:调用方先将请求参数用AES加密,再利用RSA公钥对AES的密钥值加密;
2:调用方将加密后的数据发送给服务端;
3:服务端接收到头信息里的加密串,先用RSA私钥解密出AES密钥值,再用解密出的AES密钥值解密请求参数;
4:处理完毕后,服务端再用AES密钥对响应参数加密;(本篇不涉及返回值加密,可以根据代码自己调试)
5:将加密后的结果返回给调用方。(本篇不涉及返回值解密,可以根据代码自己调试)

混合加密原因:

单纯的使用 RSA(非对称加密)方式,效率会很低,因为非对称加密解密方式虽然很保险,但是过程复杂,耗费时间长,性能不高;
RSA优势在于数据传输安全,且对于几个字节的数据,加密和解密时间基本可以忽略,所以用它非常适合加密 AES 秘钥(一般16个字节);
单纯的使用AES(对称加密)方式的话,非常不安全。这种方式使用的密钥是一个固定的密钥,客户端和服务端是一样的,一旦密钥被人获取,那么,我们所发的每一条数据都会被都对方破解;
AES有个很大的优点,那就是加密解密效率很高,而我们传输正文数据时,正好需要这种加解密效率高的,所以这种方式适合用于传输量大的数据内容。

一、RSA工具类

package com.ruoyi.common.utils.rsa;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
@Slf4j
public class ActivityRSAUtil {
/**
* 字符集
*/
public static String CHARSET = "UTF-8";
/**
* 生成密钥对
* @param keyLength  密钥长度
* @return KeyPair
*/
public static KeyPair getKeyPair(int keyLength) {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");   //默认:RSA/None/PKCS1Padding
keyPairGenerator.initialize(keyLength);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
log.info("私钥:{}" ,getPrivateKeyString(keyPair));
log.info("公钥:{}" ,getPublicKeyString(keyPair));
return keyPair;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("生成密钥对时遇到异常" +  e.getMessage());
}
}
/**
* 获取公钥
*/
public static byte[] getPublicKey(KeyPair keyPair) {
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
return rsaPublicKey.getEncoded();
}
/**
* 获取私钥
*/
public static byte[] getPrivateKey(KeyPair keyPair) {
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
return rsaPrivateKey.getEncoded();
}
/**
* 公钥字符串转PublicKey实例
* @param publicKey 公钥字符串
* @return          PublicKey
* @throws Exception e
*/
public static PublicKey getPublicKey(String publicKey) throws Exception {
byte[] publicKeyBytes = Base64.decodeBase64(publicKey.getBytes());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
/**
* 私钥字符串转PrivateKey实例
* @param privateKey  私钥字符串
* @return PrivateKey
* @throws Exception e
*/
public static PrivateKey getPrivateKey(String privateKey) throws Exception {
byte[] privateKeyBytes = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
/**
* 获取公钥字符串
* @param keyPair KeyPair
* @return  公钥字符串
*/
public static String getPublicKeyString(KeyPair keyPair){
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
String s = new String(publicKey.getEncoded());
log.info("不编码的数据:{}",s);
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(publicKey.getEncoded()));
}
/**
* 获取私钥字符串
* @param keyPair  KeyPair
* @return 私钥字符串
*/
public static String getPrivateKeyString(KeyPair keyPair){
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
return new String(org.apache.commons.codec.binary.Base64.encodeBase64((privateKey.getEncoded())));
}
/**
* 公钥加密
* @param data        明文
* @param publicKey   公钥
* @return            密文
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength());
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(bytes));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]时遇到异常"+  e.getMessage());
}
}
/**
* 私钥解密
* @param data        密文
* @param privateKey  私钥
* @return            明文
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
String str = new String(Base64.decodeBase64(data), "UTF-8");
log.info("Base64,{}",str);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE,
Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("privateKey解密字符串[" + data + "]时遇到异常"+  e.getMessage());
}
}
/**
* 私钥加密
* @param content 明文
* @param privateKey 私钥
* @return 密文
*/
public static String encryptByPrivateKey(String content, RSAPrivateKey privateKey){
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytes = rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE,content.getBytes(CHARSET), privateKey.getModulus().bitLength());
return new String(org.apache.commons.codec.binary.Base64.encodeBase64(bytes));
} catch (Exception e) {
throw new RuntimeException("privateKey加密字符串[" + content + "]时遇到异常" +  e.getMessage());
}
}
/**
* 公钥解密
* @param content  密文
* @param publicKey 私钥
* @return  明文
*/
public static String decryByPublicKey(String content, RSAPublicKey publicKey){
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
log.info("Base64.getDecoder().decode(content).toString(),{}",Base64.decodeBase64(content).toString());
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(content), publicKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("publicKey解密字符串[" + content + "]时遇到异常" +e.getMessage());
}
}
public static RSAPublicKey getRSAPublicKeyByString(String publicKey){
try {
//            org.apache.commons.codec.binary.Base64.decodeBase64(publicKeyString)
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPublicKey)keyFactory.generatePublic(keySpec);
} catch (Exception e) {
throw new RuntimeException("String转PublicKey出错" + e.getMessage());
}
}
//
public static RSAPrivateKey getRSAPrivateKeyByString(String privateKey){
try {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec);
} catch (Exception e) {
throw new RuntimeException("String转PrivateKey出错" + e.getMessage());
}
}
//rsa切割解码  , ENCRYPT_MODE,加密数据   ,DECRYPT_MODE,解密数据
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;  //最大块
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
//可以调用以下的doFinal()方法完成加密或解密数据:
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常: " + e.getMessage());
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
public static void main(String[] args) {
//        getKeyPair(1024);
//
//
//
//        RSAPublicKey rsaPublicKeyByString = getRSAPublicKeyByString(RequestDecryptionUtil.publicKey);
//
//        String aa = publicEncrypt("{\"key\":\"eViXqtVyTMPRpWVl\",\"keyVI\":\"QH9hKMwqHpcTL5Fm\",\"time\":1716531679199}", rsaPublicKeyByString);
//
//        System.out.printf(aa);
//
RSAPrivateKey rsaPrivateKeyByString = getRSAPrivateKeyByString(RequestDecryptionUtil.privateKey);
String s = privateDecrypt(aa, rsaPrivateKeyByString);
System.out.printf(s);
//
try {
s = RSAUtils.encryptByPublicKey(RequestDecryptionUtil.publicKey, "123");
System.out.println(s);
} catch (Exception e) {
throw new RuntimeException(e);
}
//        try {
//            String s1 = RSAUtils.decryptByPrivateKey(RequestDecryptionUtil.privateKey, aa);
//            System.out.println(s1);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//
//
//
//        String s = null;
//        try {
//            s = RSAUtils.encryptByPublicKey(RequestDecryptionUtil.publicKey, "123");
//            System.out.println(s);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        RSAPrivateKey rsaPrivateKeyByString = getRSAPrivateKeyByString(RequestDecryptionUtil.privateKey);
//
//        String b = privateDecrypt(s, rsaPrivateKeyByString);
//
//        System.out.printf(b);
}
}

二、AES工具类

package com.ruoyi.common.utils.rsa;
import lombok.Data;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;
@Data
public class AES256Util {
private static final String AES = "AES";
/**
* 初始向量IV, 初始向量IV的长度规定为128位16个字节, 初始向量的来源为随机生成.
*/
/**"AES/CBC/NoPadding"
* 加密解密算法/加密模式/填充方式
*/
private static final String CIPHER_ALGORITHM = "AES/CBC/NoPadding";
private static final Base64.Encoder base64Encoder = java.util.Base64.getEncoder();
private static final Base64.Decoder base64Decoder = java.util.Base64.getDecoder();
/**
* key的长度,Wrong key size: must be equal to 128, 192 or 256
* 传入时需要16、24、36
*/
private static final int KEY_LENGTH = 16 * 8;
//通过在运行环境中设置以下属性启用AES-256支持
static {
Security.setProperty("crypto.policy", "unlimited");
}
/*
* 解决java不支持AES/CBC/PKCS7Padding模式解密
*/
static {
Security.addProvider(new BouncyCastleProvider());
}
//    /**
//     * AES加密
//     */
//    public static String encode(String key, String content,String keyVI) {
//        try {
//            javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), AES);
//            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
//            cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(keyVI.getBytes()));
//            // 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
//            byte[] byteEncode = content.getBytes(java.nio.charset.StandardCharsets.UTF_8);
//            // 根据密码器的初始化方式加密
//            byte[] byteAES = cipher.doFinal(byteEncode);
//            // 将加密后的数据转换为字符串
//            return base64Encoder.encodeToString(byteAES);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//
//
//    /**
//     * 获取key
//     */
//    public static String getKey() {
//        int length = KEY_LENGTH / 8;
//        StringBuilder uid = new StringBuilder(length);
//        //产生16位的强随机数
//        Random rd = new SecureRandom();
//        for (int i = 0; i < length; i++) {
//            //产生0-2的3位随机数
//            switch (rd.nextInt(3)) {
//                case 0:
//                    //0-9的随机数
//                    uid.append(rd.nextInt(10));
//                    break;
//                case 1:
//                    //ASCII在65-90之间为大写,获取大写随机
//                    uid.append((char) (rd.nextInt(26) + 65));
//                    break;
//                case 2:
//                    //ASCII在97-122之间为小写,获取小写随机
//                    uid.append((char) (rd.nextInt(26) + 97));
//                    break;
//                default:
//                    break;
//            }
//        }
//        return uid.toString();
//    }
/**
* AES解密
*/
public static String decode(String key, String content,String keyVI) {
try {
javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), AES);
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(keyVI.getBytes(StandardCharsets.UTF_8)));
// 将加密并编码后的内容解码成字节数组
byte[] byteContent = org.apache.commons.codec.binary.Base64.decodeBase64(content.getBytes());;
// 解密
byte[] byteDecode = cipher.doFinal(byteContent);
return new String(byteDecode);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//这个是正确的
//    public static String decode(String key, String content,String keyVI){
//      try {
//        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
//        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(keyVI.getBytes(StandardCharsets.UTF_8)));
//        byte[] original = cipher.doFinal(Base64.getDecoder().decode(content));
//      return new String(original, StandardCharsets.UTF_8);
//                } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//    /**
//     * AES加密ECB模式PKCS7Padding填充方式
//     * @param str 字符串
//     * @param key 密钥
//     * @return 加密字符串
//     * @throws Exception 异常信息
//     */
//    public static String aes256ECBPkcs7PaddingEncrypt(String str, String key) throws Exception {
//        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
//        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
//        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, AES));
//        byte[] doFinal = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));
//        return new String(Base64.getEncoder().encode(doFinal));
//    }
//
//    /**
//     * AES解密ECB模式PKCS7Padding填充方式
//     * @param str 字符串
//     * @param key 密钥
//     * @return 解密字符串
//     * @throws Exception 异常信息
//     */
//    public static String aes256ECBPkcs7PaddingDecrypt(String str, String key) throws Exception {
//        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
//        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
//        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, AES));
//        byte[] doFinal = cipher.doFinal(Base64.getDecoder().decode(str));
//        return new String(doFinal);
//    }
public static void main(String[] args) {
//        String qw = encode("8L9UjJ3ImkkKoCSy", "y8CRKjEfWFxFN2or", "y8CRKjEfWFxFN2or");
//        System.out.println(qw);
//
//        String qw1 = decode("8L9UjJ3ImkkKoCSy", qw, "y8CRKjEfWFxFN2or");
//        System.out.println(qw1);
}
}

三、解密工具类

package com.ruoyi.common.utils.rsa;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.security.interfaces.RSAPrivateKey;
import java.util.Objects;
@Component
public class RequestDecryptionUtil {
private static RequestDecryptionUtil requestDecryptionUtil;
@Resource
private  ConfigurationInfo appConfig;
@PostConstruct
public void init() {
requestDecryptionUtil = this;
requestDecryptionUtil.appConfig = this.appConfig;
}
//    public final static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG3U7/0X2XOkSijPjCCFjOX2hGNb/BOW4Asx6S9Lx84ovzeFzFKy1rOLH2EpEQwjpC958Xro4neWpzXXIn8Fahun1B2qK2wggUsA3ylxpCxI53lwXvvC6rN6IU83MueInAwhVjIpqj/evf5LsZ9yp63z1wXVO7VmGYGb+kd6jOAwIDAQAB";
//    public final static String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMbdTv/RfZc6RKKM+MIIWM5faEY1v8E5bgCzHpL0vHzii/N4XMUrLWs4sfYSkRDCOkL3nxeujid5anNdcifwVqG6fUHaorbCCBSwDfKXGkLEjneXBe+8Lqs3ohTzcy54icDCFWMimqP969/kuxn3KnrfPXBdU7tWYZgZv6R3qM4DAgMBAAECgYEAomNdezCKKc9+9G3BRFCklAD8mTiS2SoYVaHuuXn34NLuDWaf+rGDaSbmy1Xl95VjFgQ2eZQkqL9Q2dvYuBxd4EiNDngkBMfFSmN5z9LqIeE8BAeUSoIfhCaXE5QEwL8765tHitveapmKmOx8NMt4HSUw6iMlimW+E+3qypL/HAECQQD5zGsshI1jN1QvlBCpJjabC5Xlf+HxSWqOZ67AQzRfKccKp8XU8/nnzrUac5xUxwi5c9NfqXuuxxYrRCda3oqDAkEAy80ucbexMBREZF3amPfBe737X7QBP3jdNYt7D5ObP+iU+jYnDh5Wstau4TdQ5kXwBunvP+j7sUiHCl4OvH9WgQJAQGpaaMx1uVQXPX2tHjFge3LtYJUtqo8ID1jlU2cBJlkbnr/M4DFaDFDdmsidU69PrKMVquGFp3hnWxjkHSauCQJAW0Evd6nZw/5/NTW1KONfFmpWAV9XY7VZz5z56FqenHonIvZWfILnLULloWCkb8eHF4FuKH7JHHOuS90b2hlmgQJAV/BWjPOD3x25AA3+2iIKM2BFCWHPOECncxNyNzG3j/D6iVQEytfqMSX7kDOrTL+cNp+GvaNm2eKKlojipOT7Mg==";
//
//    public final static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzxEEl/TfgaYVGF0CtsPX
" +
//            "Ylx3ksNZe52DJROhRoQMaRB665ozh7KtDx79zXZL47vfvh0ivlWcMPgqBmiz/s3i
" +
//            "AWmWOVd6aTUmkkDC4hAWSpkk01o5Pi+c6YtGFe1uJv+4vV9EBpW2vN2Lgg/+kAc+
" +
//            "4Vx1cD5FBvJdKaMsG6ei9hRl56VshW8xqSU28DNfhl/kWjZ12S20ZwTDjUP5YhfF
" +
//            "2OYaFLYxING86EX/Nh0RcKoQqqlDwAIxgUJx9uhMziUfwaj1oX4PgAdGkJS1VK7k
" +
//            "rZZfde7Vc6Gi6kuaDOZmtgjWM1KpJP+fnKHj9mDnDN3joAjhCwWdtTldyWDm35mJ
" +
//            "PQIDAQAB";
//    public final static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPEQSX9N+BphUY
" +
//            "XQK2w9diXHeSw1l7nYMlE6FGhAxpEHrrmjOHsq0PHv3Ndkvju9++HSK+VZww+CoG
" +
//            "aLP+zeIBaZY5V3ppNSaSQMLiEBZKmSTTWjk+L5zpi0YV7W4m/7i9X0QGlba83YuC
" +
//            "D/6QBz7hXHVwPkUG8l0poywbp6L2FGXnpWyFbzGpJTbwM1+GX+RaNnXZLbRnBMON
" +
//            "Q/liF8XY5hoUtjEg0bzoRf82HRFwqhCqqUPAAjGBQnH26EzOJR/BqPWhfg+AB0aQ
" +
//            "lLVUruStll917tVzoaLqS5oM5ma2CNYzUqkk/5+coeP2YOcM3eOgCOELBZ21OV3J
" +
//            "YObfmYk9AgMBAAECggEAR0KaDBmPmbSoadwIhRFc3FLqK63i67HHYkkhJX1oL/gl
" +
//            "9VL6DOcmu590xPLDJzqOw4SPYmVf/VJKVC5QU45TCx1lP5KlY/OQtKBo8ReMNFwD
" +
//            "2mCgdpA4Nf9iPUWatP0ofLN+W63GV7T+v+H1P2fe8fu5xskHRF7ARQYMte+5G2pG
" +
//            "rXrxG0I0ovAX6SRtVPYJ7d1VjNzK7TaPLTVPsX8aRK1ZTCygsBdfbECn9c7yfvov
" +
//            "BtknrHEKVBK1oCXfJsjVpHLUXChKBB7K8Ozj04JugqV+d7scVOpKph+vft1RDhel
" +
//            "fdLocQ2ifsNh7CKJjKbRLj5GW7AQUG89Yqfx849NWQKBgQD6AlUNrnDzLqD6RQuh
" +
//            "6NJK3ab6c49FK2HOG166naNIJJx8KCeGy7ocWXkgyl5Wtf+MCB9WnP4PWb+uC4iO
" +
//            "kUpUHkPmUQn3j7efxV1h6B/KhMHlmeGfJbNz37HaNUkl50RAVTRlO/GEE/1RlVza
" +
//            "HyXFXgeujUC8/ILgy16+DYX2VwKBgQDUB0GhfOZ/+xwex6n4qvoCgLkfV4SDJEhx
" +
//            "9oJ2a9f+FNEesKCW5GF6sllopHb3xfDYkl+g19J0aQ9J0sWQvMCvM7M7rwTPlfOh
" +
//            "zYLGlQJmlO60r9WvQWRwR5JmB9J3I1gaChAelxp2ScMkcXI47rbCDoZa2q4Ej5Vk
" +
//            "YqwvADx4iwKBgQCdLDQuarllmK3pSNj8S/NQz7I3B8lNUe2l9n0CUzIgm6upPlFD
" +
//            "I/b39aP54l+WocprTXvuJrpuCh1AHM4X2u1gnrpPJClg8oAdOKXxdE3wMq/3WVuH
" +
//            "gtsjgME+DnvTEWZOD4LmFd5LC4oY7Q63rhc/0lKAARtu9EyPaCtCzhum9wKBgBrR
" +
//            "+ClXRUj3GK2EECoWZp2ebsxaI7b7Bfb0ebhFGANZ2sIJEadEqFf+63RjKXFaJoce
" +
//            "rN4JruNuzrJF6RvP5IfFAG0STId9rl3PQzWfb7hOKovMmjkbCntxckFZx/OuEtzo
" +
//            "XPWho4VG+1pGx24QNCoD8FbZxp1pFDqoiKNBYmTVAoGBANKtrCkWvoxLuwUj6hhG
" +
//            "ml+I4uweiOBt412GOPTsWkCRXmanWAsIm7FsGPtZHCz3b9OkGZNBzGtpGSPfXzog
" +
//            "NdEQfyCDuAKNT4LlVZBPDjazA3aoijaC+4jt+TQP0DsQY9k+y/IL9kx/tvZs4NBy
" +
//            "KJS0DIosnuo2hl51F4b9o/o5";
private String privateKey;
private final static Integer timeout = 60000;
/**
*
* @param sym RSA 密文
* @param asy AES 密文
* @param clazz 接口入参类
* @return Object
*/
public static  Object getRequestDecryption(String sym, String asy, Class clazz){
//验证密钥
try {
//解密RSA
RSAPrivateKey rsaPrivateKey = ActivityRSAUtil.getRSAPrivateKeyByString(requestDecryptionUtil.appConfig.getPrivateKey());
String RSAJson = ActivityRSAUtil.privateDecrypt(sym, rsaPrivateKey);
RSADecodeData rsaDecodeData = JSONObject.parseObject(RSAJson, RSADecodeData.class);
boolean isTimeout = Objects.nonNull(rsaDecodeData)  && Objects.nonNull(rsaDecodeData.getTime())
&& System.currentTimeMillis() -  rsaDecodeData.getTime() < timeout;
if (!isTimeout){
throw new RuntimeException("Request timed out, please try again."); //请求超时
}
//解密AES
String AESJson = AES256Util.decode(rsaDecodeData.getKey(),asy,rsaDecodeData.getKeyVI());
System.out.println("AESJson: "+AESJson);
return JSONObject.parseObject(AESJson,clazz);
} catch (Exception e) {
throw new RuntimeException("RSA decryption Exception:  " +e.getMessage());
}
}
public static JSONObject getRequestDecryption(String sym, String asy){
//验证密钥
try {
//解密RSA
RSAPrivateKey rsaPrivateKey = ActivityRSAUtil.getRSAPrivateKeyByString(requestDecryptionUtil.appConfig.getPrivateKey());
String RSAJson = ActivityRSAUtil.privateDecrypt(sym, rsaPrivateKey);
RSADecodeData rsaDecodeData = JSONObject.parseObject(RSAJson, RSADecodeData.class);
//            boolean isTimeout = Objects.nonNull(rsaDecodeData)  && Objects.nonNull(rsaDecodeData.getTime()) && System.currentTimeMillis() -  rsaDecodeData.getTime() < timeout;
//            if (!isTimeout){
//                throw new RuntimeException("Request timed out, please try again."); //请求超时
//            }
//解密AES
String AESJson = AES256Util.decode(rsaDecodeData.getKey(),asy,rsaDecodeData.getKeyVI());
System.out.println("AESJson: "+AESJson);
return JSONObject.parseObject(AESJson);
} catch (Exception e) {
throw new RuntimeException("RSA decryption Exception:  " +e.getMessage());
}
}
}

四、自定义注解

package com.ruoyi.common.utils.rsa;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestRSA {
}

五、aes加密实体类

package com.ruoyi.common.utils.rsa;
import lombok.Data;
@Data
public class RSADecodeData {
private String key;
private String keyVI;
private Long time;
}

六、加密的请求参数

package com.ruoyi.common.utils.rsa;
import lombok.Data;
@Data
public class RSAEncodeData {
private String asy;
private String sym;
}

七、这里使用拦截器解密

package com.ruoyi.common.utils.rsa;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class RSAModuleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
RequestRSA annotation = method.getAnnotation(RequestRSA.class);
if (Objects.nonNull(annotation)) {
byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
String body = new String(bodyBytes, request.getCharacterEncoding());
log.info("[ WebInterceptor ] >> preHandle  requestUrI:{}  requestBody:{}", request.getRequestURI(), body);
JSONObject jsonObject = JSONObject.parseObject(body);
String asy = jsonObject.get("asy").toString();
String sym = jsonObject.get("sym").toString();
JSONObject decryption = RequestDecryptionUtil.getRequestDecryption(sym, asy);
//                Class[] parameterTypes = method.getParameterTypes();
//                // 打印方法参数类型
//                for (Class parameterType : parameterTypes) {
//                    System.out.println(parameterType.getName());
//                    Class aClass = parameterType.getClass();
Object o = JSONObject.parseObject(decryption.toJSONString(), aClass);
//                    log.info("[ 111111111 ] >> preHandle  requestUrI:{} ", aClass);
//
//
//                }
ObjectMapper objectMapper = new ObjectMapper();
// JSONObject转Map
Map map = (Map)decryption.getInnerMap();
//                Set<Map.Entry> entries = decryption.entrySet();
//                Map  map = new HashMap();
//                map.put("username","admin");
String s = objectMapper.writeValueAsString(map);
((RepeatedlyRequestWrapper) request).setBody(s.getBytes());
}
return true;
}
return true;
}
//    List argList = new ArrayList();
//    Parameter[] parameters = method.getParameters();
//        for (int i = 0; i < parameters.length; i++) {
//        //将RequestBody注解修饰的参数作为请求参数
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
if (requestBody != null) {
argList.add(args[i]);
}
//        argList.add(args[i]);
//    }
//        if (argList.size() == 0) {
//        return null;
//    } else if (argList.size() == 1) {
//        return argList.get(0);
//    } else {
//        return argList;
//    }
}

八、可以修改请求参数的request

package com.ruoyi.common.filter;
import com.ruoyi.common.utils.http.HttpHelper;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 构建可重复读取inputStream的request
* 
* @author ruoyi
*/
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
{
private  byte[] body;
public void setBody(byte[] body){
this.body = body;
}
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
{
super(request);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
body = HttpHelper.getBodyString(request).getBytes("UTF-8");
}
@Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException
{
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream()
{
@Override
public int read() throws IOException
{
return bais.read();
}
@Override
public int available() throws IOException
{
return body.length;
}
@Override
public boolean isFinished()
{
return false;
}
@Override
public boolean isReady()
{
return false;
}
@Override
public void setReadListener(ReadListener readListener)
{
}
};
}
}

九、RSA工具类

package com.ruoyi.common.utils.rsa;
import org.apache.commons.codec.binary.Base64;
import org.springframework.context.annotation.Bean;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAUtils {
// Rsa 私钥 也可固定秘钥对 若依原写法(不安全)
public static String privateKeys = "";
private static String publicKeyStr = "";
private static String privateKeyStr = "";
private static final RSAKeyPair rsaKeyPair = new RSAKeyPair();
/**
* 私钥解密
*
* @param text 待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String text) throws Exception {
return decryptByPrivateKey(rsaKeyPair.getPrivateKey(), text);
}
/**
* 公钥解密
*
* @param publicKeyString 公钥
* @param text            待解密的信息
* @return 解密后的文本
*/
public static String decryptByPublicKey(String publicKeyString, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 私钥加密
*
* @param privateKeyString 私钥
* @param text             待加密的信息
* @return 加密后的文本
*/
public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 私钥解密
*
* @param privateKeyString 私钥
* @param text             待解密的文本
* @return 解密后的文本
*/
public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 公钥加密
*
* @param publicKeyString 公钥
* @param text            待加密的文本
* @return 加密后的文本
*/
public static String encryptByPublicKey(String publicKeyString, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
public static RSAPublicKey getRSAPublicKeyByString(String publicKey){
try {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(java.util.Base64.getDecoder().decode(publicKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPublicKey)keyFactory.generatePublic(keySpec);
} catch (Exception e) {
throw new RuntimeException("String转PublicKey出错" + e.getMessage());
}
}
/**
* 构建RSA密钥对
*
* @return 生成后的公私钥信息
*/
@Bean
public void generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
rsaKeyPair.setPrivateKey(privateKeyString);
rsaKeyPair.setPublicKey(publicKeyString);
publicKeyStr = publicKeyString;
privateKeyStr = privateKeyString;
}
public static String getPublicKey() {
return publicKeyStr;
}
public static String getPrivateKey() {
return privateKeyStr;
}
public static RSAKeyPair rsaKeyPair() {
return rsaKeyPair;
}
/**
* RSA密钥对对象
*/
public static class RSAKeyPair {
private String publicKey;
private String privateKey;
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public RSAKeyPair() {
}
public RSAKeyPair(String publicKey, String privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {
return privateKey;
}
}
public static void main(String[] args) {
//        String s = null;
//        try {
//            s = encryptByPublicKey(RequestDecryptionUtil.publicKey, "123");
//            System.out.println(s);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        try {
//            String s1 = decryptByPrivateKey(RequestDecryptionUtil.privateKey, s);
//            System.out.println(s1);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
}
}

十、前端加密需要用到的js

import JSEncrypt from 'jsencrypt'
// import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
import CryptoJS from 'crypto-js'
import de from "element-ui/src/locale/lang/de";
const Base64 = require("js-base64").Base64
const publicKey= process.env.VUE_APP_PUBLICKEY;
export function rsaEncrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对数据进行加密
}
/*
* AES加密 :字符串 key iv  返回base64
*/
//加密方法
export function aesEncrypt(word, key, iv) {
const data = JSON.stringify(word);
const srcs = CryptoJS.enc.Utf8.parse(data);
// /**
//  * CipherOption, 加密的一些选项:
//  *   mode: 加密模式, 可取值(CBC, CFB, CTR, CTRGladman, OFB, ECB), 都在 CryptoJS.mode 对象下
//  *   padding: 填充方式, 可取值(Pkcs7, AnsiX923, Iso10126, Iso97971, ZeroPadding, NoPadding), 都在 CryptoJS.pad 对象下
//  *   iv: 偏移量, mode === ECB 时, 不需要 iv
//  *     返回的是一个加密对象
//  */
var key = CryptoJS.enc.Utf8.parse(key); // 密钥
var message = srcs;
var encrypted = CryptoJS.AES.encrypt(message, key, {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: CryptoJS.enc.Utf8.parse(iv) // 初始化向量
});
return  encrypted.toString();
}
/**
* 获取16位随机码AES
* @returns {string}
*/
export function get16RandomNum() {
var chars = [       '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K', 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
]
var nums = ''
//这个地方切记要选择16位,因为美国对密钥长度有限制,选择32位的话加解密会报错,需要根据jdk版本去修改相关jar包,有点恼火,选择16位就不用处理。
for (var i = 0; i < 16; i++) {
var id = parseInt(Math.random() * 61)
nums += chars[id]
}
return nums
}

十一、前端拦截器对请求统一加密

import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import {aesEncrypt, get16RandomNum, rsaEncrypt} from "@/api/encipher/encipher";
let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 5 * 60 * 1000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
let key = get16RandomNum();
let keyVI = get16RandomNum();
let time = Date.now();
let  param = {
"key":key,
"keyVI":keyVI,
"time":time
}
let data =  typeof config.data === 'object' ? JSON.stringify(config.data) : config.data
let asy = aesEncrypt(config.data,key,keyVI);
//用登陆后后端生成并返回给前端的的RSA密钥对的公钥将AES16位密钥进行加密
let sym = rsaEncrypt(JSON.stringify(param))
console.log("加密数据")
console.log(data)
console.log(asy)
console.log(sym)
let paramData = {
"asy":asy,
"sym":sym
}
console.log(paramData)
console.log(JSON.stringify(paramData))
config.data = paramData;
const requestObj = {
url: config.url,
data: paramData,
time: new Date().getTime()
}
console.log(requestObj)
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url;                  // 请求地址
const s_data = sessionObj.data;                // 请求数据
const s_time = sessionObj.time;                // 请求时间
const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time  {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
isRelogin.show = false;
store.dispatch('LogOut').then(() => {
// 如果是登录页面不需要重新加载
if (window.location.hash.indexOf("#/login") != 0) {
location.href = '/index';
}
})
}).catch(() => {
isRelogin.show = false;
});
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({
message: msg,
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code === 5000) {
MessageBox.confirm(msg, '系统提示', {
confirmButtonText: '确认',
showCancelButton: false,
type: 'warning'
})
return Promise.reject(new Error(msg))
} else if (code == 7000) {
return res.data
}else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
// 通用下载方法
export function download(url, params, filename) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob'
}).then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
})
}
export default service

十二、为什么使用拦截器不使用aop

本来是使用aop实现解密逻辑的,但是项目中使用校验的注解,发现@Validated注解会先于aop执行参数校验,所有使用拦截器。

总结

代码全部贴出来了,不仔细去讲解内容了,直接复制,拦截器这部分需要你自己添加到自己的配置文件中(如何集成拦截器知识自己查询)。所有的方法经过测试,不明白的可以留言。

本站无任何商业行为
个人在线分享 » SpringBoot整合AES+RSA加密(含前端代码)
E-->