spring boot解密数据体
有这样一个需求,拿到一份其他园区的五位一体数据对接文档,要求根据文档实现类似的服务端提供企业传输数据‘
实现方式(下文采用的是HttpMessageConverter的方式,还有其他方式暂不列举)
消息转换器
package com.lyc.wwyt.config.convert;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lyc.wwyt.exception.DecryptException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.StreamUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class DecryptingHttpMessageConverter extends MappingJackson2HttpMessageConverter {
private static final String KEY = "xxxxxxxxxxxxxxxxx";
private static final String INITIALIZATION_VECTOR = "xxxxxxxxxxxxxxxxx";
private final ObjectMapper objectMapper;
public DecryptingHttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper);
this.objectMapper = objectMapper;
setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
}
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return true;
}
@Override
public Object read(Type type, Class<?> clazz, HttpInputMessage inputMessage) throws IOException {
JavaType javaType = this.getJavaType(type, clazz);
String body = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8);
Map<String, Object> map = objectMapper.readValue(body, new TypeReference<Map<String, Object>>() {
});
String encryptedDatas = (String) map.get("datas");
String decryptedDatas = decrypt(encryptedDatas);
String decryptedBody;
if (List.class.isAssignableFrom(javaType.getRawClass())) {
List<Map<String, Object>> decryptedList = objectMapper.readValue(decryptedDatas, new TypeReference<List<Map<String, Object>>>() {
});
decryptedBody = objectMapper.writeValueAsString(decryptedList);
} else {
Map<String, Object> decryptedMap = objectMapper.readValue(decryptedDatas, new TypeReference<Map<String, Object>>() {
});
map.putAll(decryptedMap);
map.remove("datas");
decryptedBody = objectMapper.writeValueAsString(map);
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decryptedBody.getBytes());
HttpHeaders headers = inputMessage.getHeaders();
return this.objectMapper.readValue(byteArrayInputStream, javaType);
}
private String decrypt(String encrypted) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(KEY.getBytes(StandardCharsets.UTF_8), "AES");
IvParameterSpec iv = new IvParameterSpec(INITIALIZATION_VECTOR.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encrypted));
return new String(decrypted, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new DecryptException();
}
}
}
将其添加到消息转换器中
package com.lyc.wwyt.config.convert;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.util.List;
/**
* 类 WebMvcConfig
*
* @author ChenQi
* @date 2023/5/11
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Resource
private ObjectMapper objectMapper;
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(0, new DecryptingHttpMessageConverter(objectMapper));
}
}
实现效果
代码地址
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ALLBS!
评论