请求参数和应答数据统一加解密

一,针对请求参数和应答数据都是json格式时,可以通过,下面的方式,进行统一的的加解密。

1. 设置配置文件。

 @Bean
    public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
        /** SimpleModule 入参xss处理、返回BigDecimal类型处理 */
        SimpleModule module = new SimpleModule("XssStringJsonSerializer");
        module.addDeserializer(String.class,new JsonHtmlXssDeserializer(String.class));
        objectMapper.registerModule(module);

        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
        jsonConverter.setSupportedMediaTypes(mediaTypeList);
        jsonConverter.setObjectMapper(objectMapper);
        return jsonConverter;
    }

2.编写JsonHtmlXssDeserializer 类,对请求参数进行解密处理。

public class JsonHtmlXssDeserializer extends JsonDeserializer<String> {

    private static final String SM4Prefix = "Z@!@$B";

    public JsonHtmlXssDeserializer(Class<String> string) {
        super();
    }

    @Override
    public Class<String> handledType() {
        return String.class;
    }

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        String value = jsonParser.getValueAsString();
        if (value != null) {
            if(value.startsWith(SM4Prefix)){
                value = value.substring(6);
                try {
                    value = SM4.sm4Decrypt(value);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new IOException("json 解密失败");
                }
            }
            return value;
        }
        return value;
    }
}
 

编写完毕后,只要字符串的前缀为Z@!@$B时,会执行 SM4 的解密程序。

3.编写应当数据统一加密的方法

自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Documented
@JacksonAnnotationsInside
@Target(ElementType.FIELD)
@JsonSerialize(using = EncryptDataSerializer.class)
public @interface EncryptData {
    

    /**
     * 加密策略
     */
    Strategy strategy() default Strategy.SM4;

    Methods methods() default Methods.ENCRYPT;

    
    enum Strategy {
        /**
         * SM4
         */
        SM4,
        /**
         * AES
         */
        AES,
        /**
         * 从右边开始
         */
        RIGHT
    }

    enum Methods {
        /**
         * 对字段加,解密
         */
         ALL,
        /**
         * 仅加密
         */
        ENCRYPT,
        /**
         * 仅解密
         */
        DECRYPT
    }
}
 

定义aop,真对注解进行处理:

@Component
@Slf4j
@Aspect
public class DecryptAspect {

    final static Logger logger = LoggerFactory.getLogger(DecryptAspect.class);

    @Before(value = "execution(public * com.ruoyi.project.system.controller.*Controller.*(..))")
    public void before(JoinPoint joinPoint) {

        Object[] obj = joinPoint.getArgs();
        if (null != obj) {
            int len = obj.length;
            for (int i = 0; i < len; i++) {
                Object item = obj[i];
                if (item == null) {
                    return;
                }
                Field[] fields = item.getClass().getDeclaredFields();
                // 遍历所有字段
                for (Field field : fields) {
                    // 若该字段被SecurityParameter注解,则进行解密/加密
                    Class<?> fieldType = field.getType();
                    if (fieldType == String.class) {
                        EncryptData encryptData =AnnotationUtils.findAnnotation(field, EncryptData.class);
                        if (null != encryptData) {
                            // 设置private类型允许访问
                            try {
                                field.setAccessible(Boolean.TRUE);
                                handleField(item, field, encryptData);
                                field.setAccessible(Boolean.FALSE);
                            }catch (Exception ex){
                                logger.error("解压失败!",ex.fillInStackTrace());
                            }
                        }
                    }


                }
            }

        }
    }

    private  void handleField(Object item, Field field,EncryptData encryptData) throws Exception {
        if (null == item) {
            return;
        }
        if(field.get(item) == null){
            return;
        }
        String str = field.get(item).toString();
        final EncryptData.Methods methods = encryptData.methods();
        switch (encryptData.strategy()){
            case SM4:
                try {
                    if(methods == EncryptData.Methods.ALL ||
                            methods == EncryptData.Methods.DECRYPT) {
                        field.set(item,SM4.sm4Decrypt(str));
                    }

                }catch (Exception ex){
                    logger.error("sm4加密失败",ex.getCause());
                }

                return;
            case AES:
                return;
            default:
                throw new IllegalArgumentException("Illegal Sensitive Strategy");
        }

    }
}
 

EncryptDataSerializer 重新序列化接口:

public class EncryptDataSerializer extends JsonSerializer<String> implements ContextualSerializer {

    final Logger logger = LoggerFactory.getLogger(EncryptDataSerializer.class);
    private EncryptData encryptData;

    public EncryptDataSerializer(EncryptData encryptData) {

        this.encryptData = encryptData;
    }

    public EncryptDataSerializer() {
    }


    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (StringUtils.isBlank(value)) {
            gen.writeString(value);
            return;
        }

        if (encryptData != null) {
            final EncryptData.Strategy strategy = encryptData.strategy();
            final EncryptData.Methods methods = encryptData.methods();
            gen.writeString(getValue(value, strategy,methods));
        } else {
            gen.writeString(value);
        }

    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
        EncryptData annotation = property.getAnnotation(EncryptData.class);

        if (annotation != null) {
            return new EncryptDataSerializer(annotation);
        }
        return this;
    }

    private String getValue(String rawStr, EncryptData.Strategy strategy, EncryptData.Methods methods) {
       String strBack="";
        switch (strategy) {
            case SM4:
                try {
                    if(!StringUtils.isEmpty(rawStr)) {
                        if(methods == EncryptData.Methods.ALL ||
                                methods == EncryptData.Methods.ENCRYPT) {
                            strBack = SM4.sm4Encode(rawStr);
                        }
                    }
                }catch (Exception ex){
                    logger.error("sm4加密失败",ex.getCause());
                }
                return strBack;
            case AES:
                return rawStr;
            default:
                throw new IllegalArgumentException("Illegal Sensitive Strategy");
        }
    }

   
}

只要在定义的实体类上添加,EncryptData 注解,返回的字段就会sm4进行加密(注意:字段类型必须为String)

如: @EncryptData(strategy = EncryptData.Strategy.SM4,methods = EncryptData.Methods.ALL)
    /** 手机号码 */
    @Excel(name = "手机号码")
    private String phonenumber;

应答信息返回:

 phonenumber 字段会进行sm4加密。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值