后端代码如下:
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)
}