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必须得过加解密方法,当然对应处理策略统一地倒也无可厚非。