├── .gitignore
├── src
└── main
│ └── java
│ └── com
│ └── barcke
│ └── y
│ └── rsa
│ ├── annotation
│ ├── Encrypt.java
│ ├── Decrypt.java
│ └── EnableSecurity.java
│ ├── exception
│ └── EncryptRequestException.java
│ ├── pojo
│ └── KeyInfo.java
│ ├── util
│ ├── Base64Util.java
│ ├── JsonUtils.java
│ └── RSAUtil.java
│ ├── config
│ └── SecretKeyConfig.java
│ └── advice
│ ├── EncryptRequestBodyAdvice.java
│ ├── EncryptResponseBodyAdvice.java
│ └── DecryptHttpInputMessage.java
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/test/**
5 |
6 | ### STS ###
7 | .apt_generated
8 | .classpath
9 | .factorypath
10 | .project
11 | .settings
12 | .springBeans
13 | .sts4-cache
14 |
15 | ### IntelliJ IDEA ###
16 | .idea
17 | *.iws
18 | *.iml
19 | *.ipr
20 | *.log
21 | *.lck
22 | /test/
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/annotation/Encrypt.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * ,;,,;
7 | * ,;;'( 社
8 | * __ ,;;' ' \ 会
9 | * /' '\'~~'~' \ /'\.) 主
10 | * ,;( ) / |. 义
11 | *,;' \ /-.,,( ) \ 码
12 | * ) / ) / )| 农
13 | * || || \)
14 | * (_\ (_\
15 | *
16 | * @author Barcke
17 | * @version 1.0
18 | **/
19 | @Target(ElementType.METHOD)
20 | @Retention(RetentionPolicy.RUNTIME)
21 | @Documented
22 | public @interface Encrypt{
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/exception/EncryptRequestException.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.exception;
2 |
3 | /**
4 | * ,;,,;
5 | * ,;;'( 社
6 | * __ ,;;' ' \ 会
7 | * /' '\'~~'~' \ /'\.) 主
8 | * ,;( ) / |. 义
9 | *,;' \ /-.,,( ) \ 码
10 | * ) / ) / )| 农
11 | * || || \)
12 | * (_\ (_\
13 | *
14 | * @author Barcke
15 | * @version 1.0
16 | **/
17 | public class EncryptRequestException extends RuntimeException {
18 |
19 | public EncryptRequestException(String msg) {
20 | super(msg);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/pojo/KeyInfo.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.pojo;
2 |
3 | /**
4 | * ,;,,;
5 | * ,;;'( 社
6 | * __ ,;;' ' \ 会
7 | * /' '\'~~'~' \ /'\.) 主
8 | * ,;( ) / |. 义
9 | *,;' \ /-.,,( ) \ 码
10 | * ) / ) / )| 农
11 | * || || \)
12 | * (_\ (_\
13 | *
14 | * @author Barcke
15 | * @version 1.0
16 | **/
17 | public class KeyInfo {
18 | public String getPrivateKey() {
19 | return privateKey;
20 | }
21 |
22 | public void setPrivateKey(String privateKey) {
23 | this.privateKey = privateKey;
24 | }
25 |
26 | public String getPublicKey() {
27 | return publicKey;
28 | }
29 |
30 | public void setPublicKey(String publicKey) {
31 | this.publicKey = publicKey;
32 | }
33 |
34 | private String privateKey;
35 | private String publicKey;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/annotation/Decrypt.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.annotation;
2 |
3 | import com.barcke.y.rsa.exception.EncryptRequestException;
4 |
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * ,;,,;
9 | * ,;;'( 社
10 | * __ ,;;' ' \ 会
11 | * /' '\'~~'~' \ /'\.) 主
12 | * ,;( ) / |. 义
13 | *,;' \ /-.,,( ) \ 码
14 | * ) / ) / )| 农
15 | * || || \)
16 | * (_\ (_\
17 | *
18 | * @author Barcke
19 | * @version 1.0
20 | **/
21 | @Target(ElementType.METHOD)
22 | @Retention(RetentionPolicy.RUNTIME)
23 | @Documented
24 | public @interface Decrypt{
25 |
26 | /**
27 | * 请求参数一定要是加密内容
28 | * @return boolean
29 | */
30 | boolean required() default false;
31 |
32 | /**
33 | * 请求数据时间戳校验时间差
34 | * 超过(当前时间-指定时间)的数据认定为伪造
35 | * 注意应用程序需要捕获 {@link EncryptRequestException} 异常
36 | * @return long
37 | */
38 | long timeout() default 3000;
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/annotation/EnableSecurity.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.annotation;
2 |
3 | import com.barcke.y.rsa.advice.EncryptRequestBodyAdvice;
4 | import com.barcke.y.rsa.advice.EncryptResponseBodyAdvice;
5 | import com.barcke.y.rsa.config.SecretKeyConfig;
6 | import org.springframework.context.annotation.Import;
7 |
8 | import java.lang.annotation.*;
9 |
10 | /**
11 | * ,;,,;
12 | * ,;;'( 社
13 | * __ ,;;' ' \ 会
14 | * /' '\'~~'~' \ /'\.) 主
15 | * ,;( ) / |. 义
16 | *,;' \ /-.,,( ) \ 码
17 | * ) / ) / )| 农
18 | * || || \)
19 | * (_\ (_\
20 | *
21 | * @author Barcke
22 | * @version 1.0
23 | **/
24 | @Target({ElementType.TYPE})
25 | @Retention(RetentionPolicy.RUNTIME)
26 | @Inherited
27 | @Documented
28 | @Import({SecretKeyConfig.class,
29 | EncryptResponseBodyAdvice.class,
30 | EncryptRequestBodyAdvice.class})
31 | public @interface EnableSecurity{
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/util/Base64Util.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.util;
2 |
3 | import org.apache.commons.codec.binary.Base64;
4 |
5 | /**
6 | * ,;,,;
7 | * ,;;'( 社
8 | * __ ,;;' ' \ 会
9 | * /' '\'~~'~' \ /'\.) 主
10 | * ,;( ) / |. 义
11 | *,;' \ /-.,,( ) \ 码
12 | * ) / ) / )| 农
13 | * || || \)
14 | * (_\ (_\
15 | *
16 | * @author Barcke
17 | * @version 1.0
18 | **/
19 | public class Base64Util{
20 |
21 | /**
22 | * Decoding to binary
23 | * @param base64 base64
24 | * @return byte
25 | * @throws Exception Exception
26 | */
27 | public static byte[] decode(String base64) throws Exception {
28 | return Base64.decodeBase64(base64);
29 | }
30 |
31 | /**
32 | * Binary encoding as a string
33 | * @param bytes byte
34 | * @return String
35 | * @throws Exception Exception
36 | */
37 | public static String encode(byte[] bytes) throws Exception {
38 | return new String(Base64.encodeBase64(bytes) , "UTF-8");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/util/JsonUtils.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.util;
2 |
3 |
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.JsonNode;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 |
8 | import java.io.IOException;
9 |
10 | /**
11 | * ,;,,;
12 | * ,;;'( 社
13 | * __ ,;;' ' \ 会
14 | * /' '\'~~'~' \ /'\.) 主
15 | * ,;( ) / |. 义
16 | *,;' \ /-.,,( ) \ 码
17 | * ) / ) / )| 农
18 | * || || \)
19 | * (_\ (_\
20 | *
21 | * @author Barcke
22 | * @version 1.0
23 | **/
24 | public class JsonUtils {
25 |
26 | private JsonUtils() {
27 | }
28 |
29 | private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
30 |
31 | public static JsonNode getNode(String content, String key) throws IOException {
32 | JsonNode jsonNode = OBJECT_MAPPER.readTree(content);
33 | return jsonNode.get(key);
34 | }
35 |
36 | public static String writeValueAsString(Object body) throws JsonProcessingException {
37 | return OBJECT_MAPPER.writeValueAsString(body);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/config/SecretKeyConfig.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.config;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.context.annotation.Configuration;
5 |
6 | /**
7 | * ,;,,;
8 | * ,;;'( 社
9 | * __ ,;;' ' \ 会
10 | * /' '\'~~'~' \ /'\.) 主
11 | * ,;( ) / |. 义
12 | *,;' \ /-.,,( ) \ 码
13 | * ) / ) / )| 农
14 | * || || \)
15 | * (_\ (_\
16 | *
17 | * @author Barcke
18 | * @version 1.0
19 | **/
20 | @ConfigurationProperties(prefix = "rsa.encrypt")
21 | @Configuration
22 | public class SecretKeyConfig {
23 |
24 | private String privateKey;
25 |
26 | private String publicKey;
27 |
28 | private String charset = "UTF-8";
29 |
30 | private boolean open = true;
31 |
32 | private boolean showLog = false;
33 |
34 | /**
35 | * 请求数据时间戳校验时间差
36 | * 超过指定时间的数据认定为伪造
37 | */
38 | private boolean timestampCheck = false;
39 |
40 | public String getPrivateKey() {
41 | return privateKey;
42 | }
43 |
44 | public void setPrivateKey(String privateKey) {
45 | this.privateKey = privateKey;
46 | }
47 |
48 | public String getPublicKey() {
49 | return publicKey;
50 | }
51 |
52 | public void setPublicKey(String publicKey) {
53 | this.publicKey = publicKey;
54 | }
55 |
56 | public String getCharset() {
57 | return charset;
58 | }
59 |
60 | public void setCharset(String charset) {
61 | this.charset = charset;
62 | }
63 |
64 | public boolean isOpen() {
65 | return open;
66 | }
67 |
68 | public void setOpen(boolean open) {
69 | this.open = open;
70 | }
71 |
72 | public boolean isShowLog() {
73 | return showLog;
74 | }
75 |
76 | public void setShowLog(boolean showLog) {
77 | this.showLog = showLog;
78 | }
79 |
80 | public boolean isTimestampCheck() {
81 | return timestampCheck;
82 | }
83 |
84 | public void setTimestampCheck(boolean timestampCheck) {
85 | this.timestampCheck = timestampCheck;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rsa-body-spring-boot
2 | ## 使用方式
3 | 导入对应的MAVEN包:
4 |
5 | ```
6 |
7 | com.barcke.y
8 | rsa-body-spring-boot
9 | 1.0.0
10 |
11 | ```
12 | 导入对应的包后开启配置项:
13 | ```
14 | rsa:
15 | encrypt:
16 | open: true # 是否开启加密 true or false
17 | showLog: true # 是否打印加解密log true or false 默认false
18 | timestampCheck: true #是否开启时间校验 默认false
19 | publicKey: #公钥信息
20 | privateKey: #私钥信息
21 | ```
22 | 可以使用如下方法生产公私钥:
23 | ```
24 | import com.barcke.y.rsa.util.RSAUtil
25 |
26 | //用于生产公私钥 返回值为对应的公私钥信息 生成后请保管好
27 | RSAUtil.genKeyPair();
28 | ```
29 |
30 | 开启配置项后在项目中使用注解:
31 | ```
32 | @Encrypt //加密
33 | @Decrypt(required = true, timeout = 30000L) //解密 required默认关闭,timeout超时时间设置
34 | ```
35 | 示例:
36 | 
37 | **注意传参方式为“application/json”加密会对整个回参加密,解密会对整个入参解密.**
38 |
39 | 前端加解密可以同步公私钥信息、不过需要注意RSA的长度加密为117解密为256超长是会报错的~
40 | 前端加解密可参考如下:
41 | ```
42 |
43 |
44 |
45 |
46 | 使用jsencrypt执行OpenSSL的RSA加密,解密
47 |
48 |
49 |
50 |
73 |
74 |
75 | ```
76 |
77 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/advice/EncryptRequestBodyAdvice.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.advice;
2 |
3 | import com.barcke.y.rsa.annotation.Decrypt;
4 | import com.barcke.y.rsa.config.SecretKeyConfig;
5 | import com.barcke.y.rsa.exception.EncryptRequestException;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.core.MethodParameter;
10 | import org.springframework.http.HttpInputMessage;
11 | import org.springframework.http.converter.HttpMessageConverter;
12 | import org.springframework.web.bind.annotation.ControllerAdvice;
13 | import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
14 |
15 | import java.lang.reflect.Method;
16 | import java.lang.reflect.Type;
17 | import java.util.Objects;
18 |
19 | /**
20 | * ,;,,;
21 | * ,;;'( 社
22 | * __ ,;;' ' \ 会
23 | * /' '\'~~'~' \ /'\.) 主
24 | * ,;( ) / |. 义
25 | *,;' \ /-.,,( ) \ 码
26 | * ) / ) / )| 农
27 | * || || \)
28 | * (_\ (_\
29 | *
30 | * @author Barcke
31 | * @version 1.0
32 | **/
33 | @ControllerAdvice
34 | public class EncryptRequestBodyAdvice implements RequestBodyAdvice {
35 |
36 | private Logger log = LoggerFactory.getLogger(this.getClass());
37 |
38 | private boolean encrypt;
39 | private Decrypt decryptAnnotation;
40 |
41 | @Autowired
42 | private SecretKeyConfig secretKeyConfig;
43 |
44 | @Override
45 | public boolean supports(MethodParameter methodParameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
46 | Method method = methodParameter.getMethod();
47 | if (Objects.isNull(method)) {
48 | encrypt = false;
49 | return false;
50 | }
51 | if (method.isAnnotationPresent(Decrypt.class) && secretKeyConfig.isOpen()) {
52 | encrypt = true;
53 | decryptAnnotation = methodParameter.getMethodAnnotation(Decrypt.class);
54 | return true;
55 | }
56 | // 此处如果按照原逻辑直接返回encrypt, 会造成一次修改为true之后, 后续请求都会变成true, 在不支持时, 需要做修正
57 | encrypt = false;
58 | return false;
59 | }
60 |
61 | @Override
62 | public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class extends HttpMessageConverter>> converterType) {
63 | return body;
64 | }
65 |
66 | @Override
67 | public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
68 | Class extends HttpMessageConverter>> converterType){
69 | if (encrypt) {
70 | try {
71 | return new DecryptHttpInputMessage(inputMessage, secretKeyConfig, decryptAnnotation);
72 | } catch (EncryptRequestException e) {
73 | throw e;
74 | } catch (Exception e) {
75 | log.error("Decryption failed", e);
76 | }
77 | }
78 | return inputMessage;
79 | }
80 |
81 | @Override
82 | public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
83 | Class extends HttpMessageConverter>> converterType) {
84 | return body;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/barcke/y/rsa/advice/EncryptResponseBodyAdvice.java:
--------------------------------------------------------------------------------
1 | package com.barcke.y.rsa.advice;
2 |
3 | import com.barcke.y.rsa.annotation.Encrypt;
4 | import com.barcke.y.rsa.config.SecretKeyConfig;
5 | import com.barcke.y.rsa.util.Base64Util;
6 | import com.barcke.y.rsa.util.JsonUtils;
7 | import com.barcke.y.rsa.util.RSAUtil;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.core.MethodParameter;
12 | import org.springframework.http.MediaType;
13 | import org.springframework.http.converter.HttpMessageConverter;
14 | import org.springframework.http.server.ServerHttpRequest;
15 | import org.springframework.http.server.ServerHttpResponse;
16 | import org.springframework.util.StringUtils;
17 | import org.springframework.web.bind.annotation.ControllerAdvice;
18 | import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
19 |
20 | import java.lang.reflect.Method;
21 | import java.util.Objects;
22 |
23 | /**
24 | * ,;,,;
25 | * ,;;'( 社
26 | * __ ,;;' ' \ 会
27 | * /' '\'~~'~' \ /'\.) 主
28 | * ,;( ) / |. 义
29 | *,;' \ /-.,,( ) \ 码
30 | * ) / ) / )| 农
31 | * || || \)
32 | * (_\ (_\
33 | *
34 | * @author Barcke
35 | * @version 1.0
36 | **/
37 | @ControllerAdvice
38 | public class EncryptResponseBodyAdvice implements ResponseBodyAdvice