springboot项目前后端实现AES加解密

后端代码如下:

1、EncryptionUtils  这是加解密工具类

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * @ClassName EncryptionUtils
 * @Description: TODO
 * @Author LRH
 * @Date 2023/12/14
 * @Version V1.0
 **/
public class EncryptionUtils {
    /**
     * Description: 配合前端CryptoJS实现加密、解密工作。
     * CryptoJS 是一个 JavaScript 库,提供了一系列密码学函数和工具,用于加密、解密、生成摘要等任务。
     * 它支持多种加密算法,包括常见的对称加密算法(如 AES、DES)和非对称加密算法(如 RSA)。
     */


        private final static String IV = "67890123456";//需要前端与后端配置一致
        private final static String KEY = "1234567890123456";

        /**
         * 加密算法,使用默认的IV、KEY
         * @param content
         * @return
         */
        public static String encrypt(String content){
            return encrypt(content,KEY,IV);
        }

        /**
         * 解密算法,使用默认的IV、KEY
         * @param content
         * @return
         */
        public static String decrypt(String content){
            return decrypt(content,KEY,IV);
        }
        /**
         * 加密方法
         * @param content
         * @param key
         * @param iv
         * @return
         */
        public static String encrypt(String content, String key, String iv){
            try{
                // "算法/模式/补码方式"NoPadding PkcsPadding
                Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                int blockSize = cipher.getBlockSize();
                byte[] dataBytes = content.getBytes();
                int plaintextLength = dataBytes.length;
                if (plaintextLength % blockSize != 0) {
                    plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
                }
                byte[] plaintext = new byte[plaintextLength];
                System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
                SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
                IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("UTF-8"));
                cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
                byte[] encrypted = cipher.doFinal(plaintext);
                return Base64.getEncoder().encodeToString(encrypted);
            }catch (Exception e) {
                throw new RuntimeException("加密算法异常 CryptoUtil encrypt()加密方法,异常信息:" + e.getMessage());
            }
        }

        /**
         * 解密方法
         * @param content
         * @param key
         * @param iv
         * @return
         */
        public static String decrypt(String content, String key, String iv){
            try {
                byte[] encrypted1 = Base64.getDecoder().decode(content);
                Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
                SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
                IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
                byte[] original = cipher.doFinal(encrypted1);
                return new String(original).trim();
            } catch (Exception e) {
                throw new RuntimeException("加密算法异常 CryptoUtil decrypt()解密方法,异常信息:" + e.getMessage());
            }
        }

    public static void main(String[] args) {
        String str = "98B197CA526C5B2749F305DDB34233F7B8F4F9C09F83FEA6B6A2D98FFAE05A64";
        System.out.println(decrypt(str));
        }
    }

2、解码处理类DecodeInputMessage

/**
 * 解码处理
 * @author rstyro
 */
@Slf4j
public class DecodeInputMessage implements HttpInputMessage {

    private HttpHeaders headers;

    private InputStream body;

    public DecodeInputMessage(HttpInputMessage httpInputMessage) {

        try {

            // 2、从inputStreamReader 得到aes 加密的内容
            String encodeAesContent = new BufferedReader(new InputStreamReader(httpInputMessage.getBody())).lines().collect(Collectors.joining(System.lineSeparator()));
            JSONObject jsonObject = JSON.parseObject(encodeAesContent);
            // 3、AES通过密钥CBC解码
            String str = jsonObject.getString("data");
            String aesDecode = EncryptionUtils.decrypt(str);
            if (!StringUtils.isEmpty(aesDecode)) {
                // 4、重新写入到controller
                this.body = new ByteArrayInputStream(aesDecode.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public InputStream getBody() throws IOException {
        return body;
    }

    @Override
    public HttpHeaders getHeaders() {
        return headers;
    }
}

3、控制器监听EncryptRequestAdvice类
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.lang.reflect.Type;

/**
 * 请求参数到controller之前的处理
 * @author rstyro
 */
@ControllerAdvice(basePackages = {"shengyun.controller"})
public class EncryptRequestAdvice implements RequestBodyAdvice {


    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
            return new DecodeInputMessage(httpInputMessage);
    }

    @Override
    public Object afterBodyRead(Object obj, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        // 这里就是已经读取到body了,obj就是
        return obj;
    }

    @Override
    public Object handleEmptyBody(Object obj, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        // body 为空的时候调用
        return obj;
    }

}

4、结果返回工具类
 

public class ResultUtil {
    private static Logger logger = LoggerFactory.getLogger(ResultUtil.class);
    public static ResultVO<Object> success(Object object) {
        ResultVO<Object> resultVO = new ResultVO<>();
        if(object instanceof String){
            resultVO.setData(object);
        }else {
            // 配置项
            SerializerFeature feature = SerializerFeature.WriteDateUseDateFormat;
            resultVO.setData(EncryptionUtils.encrypt(JSONObject.toJSONString(object,feature)));
        }
        resultVO.setCode(200);
        resultVO.setMsg("success");
        logger.info("返回参数:{}", JSONObject.toJSONString(resultVO));
        return resultVO;
    }

    public static ResultVO<Object> success() {
        return success(null);
    }
    public static ResultVO<Object> success(Object object, String msg) {
        ResultVO<Object> resultVO = new ResultVO<>();
        resultVO.setData(object);
        resultVO.setCode(200);
        resultVO.setMsg(msg);
        return resultVO;
    }
    public static ResultVO<Object> error(Integer status, String msg) {
        ResultVO<Object> resultVO = new ResultVO<>();
        resultVO.setCode(status);
        resultVO.setMsg(msg);
        return resultVO;
    }
}
5、接口返回实体类
@Data
public class ResultVO<T> implements Serializable {
    private Integer code;
    private String msg;
    private T data;
}

前端引入import CryptoJS from '@/uni_modules/crypto-js'

// 密钥和偏移量
const key = 'your-key'
const iv = 'your-iv'


// 加密函数
const encrypt = (data) => {
  const keyBytes = CryptoJS.enc.Utf8.parse(key)
  const ivBytes = CryptoJS.enc.Utf8.parse(iv)
debugger
  const encrypted = CryptoJS.AES.encrypt(data, keyBytes, {
    iv: ivBytes,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.NoPadding,
  })

  return encrypted.toString()
}


// 解密函数
const decrypt = (encryptedData) => {
  const cipherText = CryptoJS.enc.Base64.parse(encryptedData);
  const keyBytes = CryptoJS.enc.Utf8.parse(key);
  const ivBytes = CryptoJS.enc.Utf8.parse(iv);

  const decipher = CryptoJS.AES.decrypt(
    {
      ciphertext: cipherText,
    },
    keyBytes,
    {
      iv: ivBytes,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.NoPadding,
    }
  );

  const decryptedData = CryptoJS.enc.Utf8.stringify(decipher);
  return decryptedData;
}

// GET请求
const get = (data = {}, options = {}) => {
    options.showLoading = data.showLoading || true
    options.url = data.url
    options.method = 'GET'
    options.data = encrypt(data.data)
    return request(options)
}

// POST请求
const post = (data = {}, options = {}) => {
    options.showLoading = data.showLoading || true
    options.showMask = data.showMask || false
    options.showErrorToast = data.showErrorToast!=1
    options.isForm = data.isForm || false
    options.url = data.url
    options.method = 'POST'
    options.data = encrypt(data.data)
    return request(options)
}

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们可以使用RSA算法来加密AES的密钥,然后使用AES算法来加密数据。 1. 生成RSA公私钥对 ```java KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(2048); KeyPair keyPair = generator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); ``` 2. 使用RSA公钥加密AES密钥 ```java // 生成AES密钥 KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); // 使用RSA公钥加密AES密钥 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedKey = cipher.doFinal(secretKey.getEncoded()); ``` 3. 使用AES密钥加密数据 ```java // 使用AES密钥加密数据 byte[] rawData = "hello world".getBytes("UTF-8"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encryptedData = cipher.doFinal(rawData); ``` 4. 使用RSA私钥解密AES密钥 ```java // 使用RSA私钥解密AES密钥 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedKey = cipher.doFinal(encryptedKey); SecretKey originalKey = new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); ``` 5. 使用AES密钥解密数据 ```java // 使用AES密钥解密数据 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, originalKey); byte[] decryptedData = cipher.doFinal(encryptedData); ``` 注意事项: - AES密钥需要保密,不能直接传输或存储。 - RSA加密的数据长度不能超过RSA公钥的长度。因此,如果需要加密的数据较长,可以使用AES算法对数据进行分块加密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值