Spring 接口数据加解密---全局加解密篇

Spring 接口数据加解密—全局加解密篇

  • 数据加密传输
  • 加解密处理
  • 自定义message-converters
  • 小结

数据加密传输

企业级开发,是缺少不了数据的加密传输。如若不是,请自重。微信公共号的开发便提供AES加密处理,提高公共号的安全性。

加解密处理

(一) 请求数据加密算法加密生成字符串,按照MediaType=text/plain请求访问,服务器接收到字符串,并对字符串进行解密。响应结果加密生成字符串,并响应。
优势:随性。
劣势:仅能处理字符串,字符串明文也有被破解风险。且比如RC4算法加密后生成的字节转字符串是解密不了的。
(二) 自定义message-converters,消息转换器的调用完全依照请求的MediaType信息(本文详细介绍,目前restful主流,这里针对json串处理)。
优势:仅需实现接口,简单配置。
劣势:对同一类型的MediaType都进行加解密操作。
(三) 使用spring提供的接口RequestBodyAdvice和ResponseBodyAdvice对数据加解密。
优势:可指定接口加解密,无需配置。
劣势:需要升级spring4.2及以上。
(四) 使用拦截器,进行处理。

自定义message-converters

applicationContext.xml 中配置自定义的消息转换器:

<mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
             <!-- 配置自定义转换器com.JsonMessageConverter-->
            <bean  class="com.JsonMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="serializationInclusion">
                            <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">ALWAYS</value>
                        </property>
                    </bean>
                </property>
                <property name="supportedMediaTypes">
                    <list>
                        <!--自定义转换器可处理的MediaType  只要是请求头是这几种类型便自然被这个转换器处理-->
                        <value>text/html;charset=UTF-8</value>
                        <value>text/json;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

实现消息转换器com.JsonMessageConverter,这里是针对json的,所以继承MappingJackson2HttpMessageConverter。

package com;
public class CustomerJsonMessageConverter extends MappingJackson2HttpMessageConverter {

    //数据读前
    @Override
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException,
            HttpMessageNotReadableException {
        JavaType javaType = this.getJavaType(clazz, (Class) null);

        InputStream is = inputMessage.getBody();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] b = new byte[4096];
        int n = 0;
        while ((n = is.read(b)) > 0) {
            out.write(b, 0, n);
        }
        //解密 解密
        String plainBody = decrypt(out);
        try {
            return this.objectMapper.readValue(new ByteArrayInputStream(plainBody.getBytes()), javaType);
        } catch (IOException ex) {
            throw new HttpMessageNotReadableException("Could not read document: " + ex.getMessage(), ex);
        }
    }

    //数据写后
    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException,
            HttpMessageNotWritableException {
        String plainRspJson = objectMapper.writeValueAsString(object);
        //加密
        outputMessage.getBody().write(encrypt(plainRspJson.getBytes()));
    }
}

@requestBody和@responseBody这两个注解,对应readInternal(读前)在这个方法进行解密,然后重写writeInternal(写后)在这个方法进行加密输出。

小结

如上看出加解密处理还是很简单,但是缺点也是显而易见的,对同一类型指定的MediaType必须得过加解密方法,当然对应处理策略统一地倒也无可厚非。

猜你喜欢

转载自blog.csdn.net/ccycc88/article/details/80569816