package com.tiesheng.encrypt.config; import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.ECKeyUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.hutool.log.LogFactory; import com.tiesheng.annotation.encrypt.EncryptedRespBody; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** * @author hao */ @ControllerAdvice public class EncryptResponseBodyAdvice implements ResponseBodyAdvice { @Autowired EncryptConfig encryptConfig; @Override public boolean supports(MethodParameter returnType, Class> converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (!encryptConfig.isEnable()) { return body; } boolean encrypt = AnnotationUtil.getAnnotation(returnType.getContainingClass(), EncryptedRespBody.class) != null; if (!encrypt) { return body; } try { String content = JSONUtil.toJsonStr(body); String respData = JSONUtil.parseObj(content).getStr("data"); if (StrUtil.isEmpty(respData)) { // 无需加密 return body; } JSONObject resp = JSONUtil.parseObj(content); resp.set("encrypted", true); if (resp.getInt("code") == 200) { // 用公钥进行加密 ECPrivateKeyParameters privateKeyParameters = ECKeyUtil.toSm2PrivateParams(encryptConfig.getPrivateQ()); ECPublicKeyParameters publicKeyParameters = ECKeyUtil.getPublicParams(privateKeyParameters); SM2 sm2 = SmUtil.sm2(privateKeyParameters, publicKeyParameters); String decrypt = sm2.encryptHex(respData, KeyType.PublicKey); resp.set("data", decrypt.substring(2)); } return resp; } catch (Exception var17) { LogFactory.get().info("加密数据异常", var17); } return body; } }