版本更新记录
更新的功能具体使用示例已经更新到博文中,请在目录中找到对应位置查看
最新版本:1.4
优化自定义解密过程功能,使其只覆盖默认解密方式,注解中指定其他解密方式不受影响;
1.3版本
新增map类型参数解密;
新增不同接口不同解密方式配置;
1.2版本
新增全局解密配置和忽略解密注解;
新增自定义解密过程接口;
介绍
用来实现接口参数解密的工具,只需引入依赖,在配置文件写明加密的配置,在接口上使用指定注解即可实现该接口的参数解密。并支持使用validation模块的注解进行参数校验,支持分组校验功能
支持的对称加密方式:SM4,AES,DES,DESede 支持的非对称加密方式:RSA,SM2
软件架构
使用java8,springboot2.x.x,一个简单的springboot starter 启动器,功能中用到的工具类是hutool
配置教程
1.引入依赖
<dependency> <groupId>io.github.vhukze</groupId> <artifactId>master-key-spring-boot-starter</artifactId> <version>目前最新版本</version> </dependency>
2.配置
注册参数解析器
import com.vhukze.masterkey.master.DecodeResolver; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; import java.util.List; /** * webmvc配置 */ @Configuration public class MasterKeyConfig implements WebMvcConfigurer { @Resource private DecodeResolver decodeResolver; /** * 注册自定义HandlerMethodArgumentResolver 接口参数解密 */ @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(decodeResolver); } }
对称加密配置示例(配置到application.yml中)
master-key: # 加密方式 encode: SM4 # 使用json格式参数时,解密之前json的key 不配置此参数则代表使用text格式参数,只传递加密后的字符串 json-key: str # 加密模式 mode: CBC # 填充方式 padding: ISO10126Padding # 秘钥 key: 1234123412ABCDEF # 盐值 salt: ABCDEF1234123412 # 是否开启全局解密 默认false global-decode: false
对称加密配置示例(配置到application.yml中)
加密方式(encode) | 加密模式(mode) |
填充方式(padding) |
SM4 |
NONE |
NoPadding |
AES |
CBC |
ZeroPadding |
DES |
CFB |
ISO10126Padding |
DESede |
CTR |
OAEPPadding |
CTS |
PKCS1Padding |
|
ECB |
PKCS5Padding |
|
OFB |
SSL3Padding |
|
PCBC |
非对称加密配置示例
master-key: # 加密方式 encode: SM2 # 使用json格式参数时,解密之前json的key 不配置此参数则代表使用text格式参数,只传递加密后的字符串 json-key: # 公钥 public-key: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEDRhJQbkA5SKceAaJmtdOBiRzCqwei4WRzAkBrZ9SkBZhZ1zC4nteRLVi754MsI/8vsiNK2lV518E8RaNw+mnLA== # 私钥 private-key: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQ # 是否开启全局解密 默认false global-decode: false
3.注意事项
使用SM4和SM2国密加密算法时,需要引入国密加密的依赖 如下
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15to18</artifactId> <version>1.69</version> </dependency>
使用说明
支持自定义实体类、基础数据类型及其包装类、集合类型。加密前参数格式跟正常请求接口时相同
不同传参方式示例
例如当前接口所需参数为:{"id":1,"count":4}
加密后为:c7dc378bf0c4da001466818765813a506b1a6b37e960b7ca
1.json格式传参
在配置文件配置好json-key,并使用配置的json-key构建json字符串,比如配置的json-key为str,json字符串如下
{ "str":"c7dc378bf0c4da001466818765813a506b1a6b37e960b7ca" }
实际请求如下图
2.text格式传参
不配置json-key即为使用text格式传参
实际请求如下图
不同参数类型示例
使用text传参方式演示
接口使用@ParamsDecode注解,标明此接口需要参数解密,如下
@ParamsDecode @PostMapping("decode") public String decode(Stock stock){ return ""; }
如果在配置中开启了全局解密,则无需使用 @ParamsDecode注解,会对所有接口进行解密。可以使用@IngoreDecode注解标明此接口无需解密,如下
@IgnoreDecode @PostMapping("decode") public String decode(Stock stock){ return ""; }
1.自定义实体类
接口参数的实体类
@Data public class Stock { private Integer id; private Integer count; }
加密前的请求参数: {"id":1,"count":4}
实际请求
接口接收到的参数
2.基础数据类型或其包装类
接口参数为一个int类型
加密前的请求参数:5
实际请求
接口接收到的参数
3.集合类型
接口参数为List集合
加密前的请求参数:[1,2,3]
实际请求
接口接收到的参数
4.map类型
要处理map类型,还需要新增两个配置,如下
1、在注册参数解析器的MasterKeyConfig中新增下面内容
@Resource private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @PostConstruct public void init() { List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>(); newResolvers.add(decodeResolver); newResolvers.addAll(requestMappingHandlerAdapter.getArgumentResolvers()); requestMappingHandlerAdapter.setArgumentResolvers(newResolvers); }
2、在配置文件中开启允许循环依赖:spring.main.allow-circular-references=true
接口参数为Map
加密前的请求参数:{"id":3, "count":4}
实际请求
接口接收到的参数
自定义解密过程
新建一个类实现MkDecodeInterface接口,并实现其中decode方法,使用@Component注添加到ioc容器中即可,如下所示,是一个简单的去括号功能
注意:实现了自定义解密接口,就会使用自定义解密,配置文件的配置无效(全局解密和json-key配置不受影响)
package com.vhukze.lockdemo.config; import com.vhukze.masterkey.abs.MkDecodeInterface; import org.springframework.stereotype.Component; /** * 集成自定义解密功能 */ @Component public class MkDecodeInterfaceImpl implements MkDecodeInterface { @Override public String decode(String before) { return before.replaceAll("\\(", "").replaceAll("\\)", ""); } }
实际请求
接口接收到的参数
不同接口使用不同解密方法
为了解决项目中使用的不止一个加密方式,不同接口需要使用不同的解密方式
首先在配置文件中配置多个解密配置,示例如下:
一个全局解密配置和两个单独解密配置
master-key: # 是否开启全局解密 默认false # global-decode: true # 加密方式 encode: DESede # 解密前json的key json-key: # 加密模式 mode: CBC # 填充方式 padding: ISO10126Padding # 秘钥 key: 1234123412ABCDEF12ABCDEF # 盐值 salt: ABCDEF12 # 多个解密配置 这个名称是自定义的,使用时在注解中指定 config1: # 加密方式 encode: AES # 解密前json的key json-key: # 加密模式 mode: CBC # 填充方式 padding: ISO10126Padding # 秘钥 key: 1234123412ABCDEF # 盐值 salt: ABCDEF1234123412 config2: # 加密方式 encode: DES # 解密前json的key json-key: # 加密模式 mode: CBC # 填充方式 padding: ISO10126Padding # 秘钥 key: 1234123412ABCDEF # 盐值 salt: ABCDEF12
使用时在注解中指定value字段值即可,如下
@ParamsDecode("config1") @PostMapping("decode") public String decode(Stock stock) { return ""; }
指定value字段值之后,此接口便会使用注解中指定的配置解密
validation模块注解校验
实现了一些常用的注解,并支持分组校验功能,目前实现的注解有以下这些
数据类型 |
注解 |
Integer、Long、Short |
@NotNull、@Max、@Min、@Null |
String |
@NotNull、@NotBlank、@Size、@Null、@Pattern |
集合类型 |
@NotNull、@NotBlank、@Size、@Null、@Pattern |
具体使用方式跟正常使用一样,下面有个示例
@Data public class Stock { @Max(3) @NotNull(groups = Edit.class) private Integer id; @NotBlank(groups = {Add.class, Edit.class}) private String name; @Min(3) private Integer count; public interface Add { } public interface Edit { } }
@ParamsDecode @PostMapping("decode") public String decode(@Validated(value = Add.class) Stock stock) { return ""; }
最后
目前就有这些功能,如果有其他需求,欢迎提出,后续增加。