学习加密(⼆)SpringBoot使⽤AES对称加密,前后端传递参数
加解密
前⾔:
1.最近要做⼀个安全性稍微⾼⼀点的项⽬,⾸先就想到了要对参数加密,和采⽤https协议.
2.以前对加密这块不了解,查阅了很多资料,加密⽅式很多种,但是⼤概区分两种,⼀个就是对称加密(DES,3DES,AES,IDEA等),另外⼀个就是⾮对称加密(RSA,Elgamal,背包算法,Rabin,D-H等)
3.这两种区别还是有的,粗浅的说:
(1)对称加密⽅式效率⾼,但是有泄露风险
(2)⾮对称加密⽅式效率⽐对称加密⽅式效率低,但是基本上没有泄露风险
使⽤对称加密⽅式(AES)实践:
1.创建spring boot项⽬,导⼊相关依赖
2.编写加密⼯具类
3.编写⾃定义注解(让加解密细粒度)
4.编写⾃定义DecodeRequestAdvice和EncodeResponseBodyAdvice
5.创建controller
6.创建jsp或者html,引⼊js(加密和解密的通⽤js)
ps:因为这⾥没https证书,所有使⽤http, 考虑到前后端分离,使⽤json来传递数据
第⼀步: 略,不会的请⾃⾏百度spring boot项⽬如何创建!
第⼆步:
pto.Cipher;
pto.KeyGenerator;
pto.spec.SecretKeySpec;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.JSONPObject;
import dec.binary.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* 前后端数据传输加密⼯具类
* @author monkey
*
*/
public class AesEncryptUtils {
//可配置到Constant中,并读取配置⽂件注⼊,16位,⾃⼰定义
private static final String KEY = "xxxxxxxxxxxxxxxx";
//参数分别代表算法名称/加密模式/数据填充⽅式
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* 加密
* @param content 加密的字符串
* @param encryptKey key值
* @return
* @throws Exception
*/
public static String encrypt(String content, String encryptKey) throws Exception {
KeyGenerator kgen = Instance("AES");
kgen.init(128);
Cipher cipher = Instance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new Bytes(), "AES")); byte[] b = cipher.Bytes("utf-8"));
// 采⽤base64算法进⾏转码,避免出现中⽂乱码
deBase64String(b);
}
/**
* 解密
* @param encryptStr 解密的字符串
* @param decryptKey 解密的key值
* @return
* @throws Exception
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
KeyGenerator kgen = Instance("AES");
kgen.init(128);
Cipher cipher = Instance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new Bytes(), "AES")); // 采⽤base64算法进⾏转码,避免出现中⽂乱码
byte[] encryptBytes = Base64.decodeBase64(encryptStr);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
public static String encrypt(String content) throws Exception {
return encrypt(content, KEY);
}
public static String decrypt(String encryptStr) throws Exception {
return decrypt(encryptStr, KEY);
}
public static void main(String[] args) throws Exception {
Map map=new HashMap<String,String>();
map.put("key","value");
map.put("中⽂","汉字");
String content = JSONString(map);
System.out.println("加密前:" + content);
String encrypt = encrypt(content, KEY);
System.out.println("加密后:" + encrypt);
String decrypt = decrypt(encrypt, KEY);
System.out.println("解密后:" + decrypt);
}
}
第三步:
import org.springframework.web.bind.annotation.Mapping;
import java.lang.annotation.*;
/
**
* @author monkey
* @desc 请求数据解密
* @date 2018/10/25 20:17
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Mapping
@Documented
public @interface SecurityParameter {
/**
* ⼊参是否解密,默认解密
*/
boolean inDecode() default true;
/**
* 出参是否加密,默认加密
*/
boolean outEncode() default true;
}
第四步:
DecodeRequestAdvice类
import org.apachemons.io.IOUtils;
import org.apachemons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.verter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.hod.annotation.RequestBodyAdvice;
import java.io.IOException;
import java.io.InputStream;
import flect.Type;
/**
* @author monkey
* @desc 请求数据解密
* @date 2018/10/25 20:17
*/
@ControllerAdvice(basePackages = "ller")
public class DecodeRequestBodyAdvice implements RequestBodyAdvice {
private static final Logger logger = Logger(DecodeRequestBodyAdvice.class);
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMes
return body;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageC try {
boolean encode = false;
if (Method().isAnnotationPresent(SecurityParameter.class)) {
//获取注解配置的包含和去除字段
SecurityParameter serializedField = MethodAnnotation(SecurityParameter.class);
//⼊参是否需要解密
encode = serializedField.inDecode();
}
if (encode) {
logger.info("对⽅法method :【" + Method().getName() + "】返回数据进⾏解密");
return new MyHttpInputMessage(inputMessage);
}else{
return inputMessage;
}
} catch (Exception e) {
e.printStackTrace();
<("对⽅法method :【" + Method().getName() + "】返回数据进⾏解密出现异常:"+e.getMessage());
return inputMessage;
}
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessa return body;
}
class MyHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
this.headers = Headers();
this.body = InputStream(AesEncryptUtils.decrypt(Body(), "UTF-8"))), "UTF-8");
}
@Override
public InputStream getBody() throws IOException {
return body;
springboot推荐算法}
@Override
public HttpHeaders getHeaders() {
return headers;
}
/**
*
* @param requestData
* @return
*/
public String easpString(String requestData){
if(requestData != null && !requestData.equals("")){
String s = "{\"requestData\":";
if(!requestData.startsWith(s)){
throw new RuntimeException("参数【requestData】缺失异常!");
}else{
int closeLen = requestData.length()-1;
int openLen = "{\"requestData\":".length();
String substring = StringUtils.substring(requestData, openLen, closeLen);
return substring;
}
}
return "";
}
}
EncodeResponseAdvice类:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.hod.annotation.ResponseBodyAdvice;
/**
* @author monkey
* @desc 返回数据加密
* @date 2018/10/25 20:17
*/
@ControllerAdvice(basePackages = "ller")
public class EncodeResponseBodyAdvice implements ResponseBodyAdvice {
private final static Logger logger = Logger(EncodeResponseBodyAdvice.class);
@Override
public boolean supports(MethodParameter methodParameter, Class aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpReques boolean encode = false;
if (Method().isAnnotationPresent(SecurityParameter.class)) {
//获取注解配置的包含和去除字段
SecurityParameter serializedField = MethodAnnotation(SecurityParameter.class);
//出参是否需要加密
encode = serializedField.outEncode();
}
if (encode) {
logger.info("对⽅法method :【" + Method().getName() + "】返回数据进⾏加密");
ObjectMapper objectMapper = new ObjectMapper();
try {
String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);
pt(result);
} catch (Exception e) {
e.printStackTrace();
<("对⽅法method :【" + Method().getName() + "】返回数据进⾏解密出现异常:"+e.getMessage());
}
}
return body;
}
}
第五步:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论