Popular MVC框架请求响应数据加解密@Decrypt和@Encrypt的使用示例

简介

此项目用于演示popularmvc如何提供统一全自动化的API隐私数据保护,并且可以做到业务无感和灵活指定数据加解密算法。

请求数据加密使用@Decrypt注解,响应信息加密使用@Encrypt注解,使用自定义算法进行加解密请实现DataEncryptHandler接口,注解中指定即可。

  1. 请求数据解密
  2. 响应信息加密
  3. 指定自定义解密算法
  4. 指定自定义加密算法

项目示例

1 项目结构

  • 项目结构

    │  pom.xml
    │  README.md
    │      
    ├─src
    │  ├─main
    │  │  ├─java
    │  │  │  └─com
    │  │  │      └─danyuanblog
    │  │  │          └─framework
    │  │  │              └─demo
    │  │  │                  └─popularmvc
    │  │  │                      │  StartDemoApplication.java
    │  │  │                      │  
    │  │  │                      ├─component
    │  │  │                      │      RSADataEncryptHandler.java
    │  │  │                      │      
    │  │  │                      ├─controller
    │  │  │                      │  │  TestCustomEncryptAndDecryptController.java
    │  │  │                      │  │  TestEncryptAndDecryptController.java
    │  │  │                      │  │  
    │  │  │                      │  └─dto
    │  │  │                      │          UserInfoDto.java
    │  │  │                      │          
    │  │  │                      └─utils
    │  │  │                              RSAEncryptUtil.java
    │  │  │                              
    │  │  └─resources
    │  │          application.yml
    │  │          
    │  └─test
    │      └─java
    │          └─com
    │              └─danyuanblog
    │                  └─framework
    │                      └─popular
    │                          └─mvc
    └─target
        ├─classes
        │  │  application.yml
        │  │  
        │  └─com
        │      └─danyuanblog
        │          └─framework
        │              └─demo
        │                  └─popularmvc
        │                      │  StartDemoApplication.class
        │                      │  
        │                      ├─component
        │                      │      RSADataEncryptHandler.class
        │                      │      
        │                      ├─controller
        │                      │  │  TestCustomEncryptAndDecryptController.class
        │                      │  │  TestEncryptAndDecryptController.class
        │                      │  │  
        │                      │  └─dto
        │                      │          UserInfoDto.class
        │                      │          
        │                      └─utils
        │                              RSAEncryptUtil.class
        │                              
        └─test-classes
            └─com
                └─danyuanblog
                    └─framework
                        └─popular
                            └─mvc
    
  • 引入模块依赖,在pom.xml添加

	<dependency>
		<groupId>com.danyuanblog.framework</groupId>
		<artifactId>popular-web-mvc</artifactId>
		<version>${popular-web-mvc.version}</version>
	</dependency>

2 启用PopularMvc框架

/**  
* Title StartDemoApplication.java  
* Description  
* @author danyuan
* @date Oct 31, 2020
* @version 1.0.0
* site: www.danyuanblog.com
*/ 
package com.danyuanblog.framework.demo.popularmvc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.danyuanblog.framework.popularmvc.annotation.EnablePopularMvc;

@SpringBootApplication
@EnablePopularMvc
public class StartDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(StartDemoApplication.class, args);
	}
}

3 配置信息

秘钥信息配置如下application.yml

popularmvc:
  api: 
    channels:
      default: #用于不区分渠道信息的应用
        default: #默认的秘钥信息
          enable: true
          #用于对称加解密、生成数字签名、验证数字签名的秘钥
          secret: "123456"
          keyPair: #用于非对称加解密的秘钥对
            privateSecret: "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIZjqviU3YAn3yOftco++Ya+KcuE6hC3scAvh7CoC4bgYTAqWZhNmdXOu4I5jzd2rhz2r6E6CInRhhY+m9kRIKN8GKP7hsG2/GibY/iK304zxqetzhvX9jd8D/f9riTqd6N09g3zBkmh6XUBvbha52Xksi4UzXJhV3ZVgfWv1t4nAgMBAAECgYByVrQtQQLfuYypE4Yo58GHOZ33sUMwLAoImKfazm7YN2mZAD8wTL3Y4kY4ut418zyaGew9wVFoaKKrpGMWoPLhvZiMZGb92r5SIb4C9gI3S6XHKYoOaVXi8oSTkCF0duoSQdCy3w3CGZbdfTEO/qtT25CePyGB2c1bYj0VULUm2QJBAPTzhh5ndTyuGiV+wbnWk6x6gcONNUGpTuvdGkcNBw/fn6QAA44CA+LKdFOMDB2QQmO3vF/JhQEjG6L4mbq8A6UCQQCMc3l40RwRypJ3A9RbwrYtO1c0X2VHdGCpi1L4FMxLWdTB0c7y9HbbXcJdL0L3Bl48Go0bwzzNSkfr2vqR9MDbAkBcZqjHO1u8QijW0BQgGFOokqX0sIXQeR+uVb+d4coyMLc11FOC9DunB5wOEBxZ4ptIpnzG3Wvw29+HAKRtDpOJAkBwoBSTTlPM7H0glOCQKIY/pSsbozeq4ea1bjS9HKhp8AIM3jquVlyNMhUu9jwjrGaamcv3rEqwcFVWC0YNDpArAkBYjalgYWGq6hRTjYSYJ82mdHy2EGxGhBkq51U871uaReP8c/a5wGjxPEyZMclF5+fpfFTwD+F8JZReVqa70eh6df723820"
            publicSecret: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGY6r4lN2AJ98jn7XKPvmGvinLhOoQt7HAL4ewqAuG4GEwKlmYTZnVzruCOY83dq4c9q+hOgiJ0YYWPpvZESCjfBij+4bBtvxom2P4it9OM8anrc4b1/Y3fA/3/a4k6nejdPYN8wZJoel1Ab24Wudl5LIuFM1yYVd2VYH1r9beJwIDAQAB"
        appId1: #某个应用下的秘钥信息
          enable: true
          #用于对称加解密、生成数字签名、验证数字签名的秘钥
          secret: "123456"
          keyPair: #用于非对称加解密的秘钥对
            privateSecret: ""
            publicSecret: ""
      android:
        default:
          enable: true
          #用于对称加解密、生成数字签名、验证数字签名的秘钥
          secret: "123456"
          keyPair: #用于非对称加解密的秘钥对
            privateSecret: ""
            publicSecret: ""
      ios: 
        default: 
          enable: true
          secret: "12345678"  
          keyPair:
            privateSecret: ""
            publicSecret: ""  

4 演示代码解析

4.1 使用默认的AES进行加解密

API数据的加解密的使用主要分两种应用场景:

  1. 对api调用者传递过来的接口请求内的隐私信息进行解密,然后交由业务去处理,popularmvc对业务屏蔽了加解密的过程,业务可以直接使用明文进行处理

  2. 将API返回隐私信息加密后再返回给接口调用者,接口调用者拿到后再进行解密后处理

示例代码如下所示。

  • 接口源码TestEncryptAndDecryptController.java

    /**  
    * Title TestEncryptAndDecryptController.java  
    * Description  
    * @author danyuan
    * @date Jan 4, 2021
    * @version 1.0.0
    * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.framework.demo.popularmvc.controller;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.danyuanblog.framework.demo.popularmvc.controller.dto.UserInfoDto;
    import com.danyuanblog.framework.popularmvc.annotation.Decrypt;
    import com.danyuanblog.framework.popularmvc.annotation.Encrypt;
    
    @Api(tags = "测试接口数据安全传输功能")
    @RestController
    public class TestEncryptAndDecryptController {
    
    	@GetMapping(value="testDecryptParamAndResponse",
    			name="测试加解密普通参数和响应信息")
    	@ApiOperation(value="测试加解密普通参数和响应信息", notes="测试加解密普通参数和响应信息")
    	@Encrypt
    	public UserInfoDto testDecryptParamAndResponse(@RequestParam("desc") @Decrypt String desc) {
    		UserInfoDto user = new UserInfoDto();
    		user.setUsername("danyuan");
    		user.setAge(18);
    		user.setDesc("this is a encrypt test .");		
    		return user;
    	}
    	
    	@GetMapping(value="testEncryptListResponseData",
    			name="测试加密列表响应信息")
    	@ApiOperation(value="测试加密列表响应信息", notes="测试加密列表响应信息")
    	public List<UserInfoDto> testEncryptListResponseData(){
    		List<UserInfoDto> list = new ArrayList<>();
    		UserInfoDto user1 = new UserInfoDto();
    		user1.setUsername("danyuan");
    		user1.setAge(18);
    		user1.setDesc("this is a encrypt test 1 .");
    		UserInfoDto user2 = new UserInfoDto();
    		user2.setUsername("小明");
    		user2.setAge(22);
    		user2.setDesc("this is a encrypt test 2 .");
    		list.add(user1);
    		list.add(user2);
    		return list;
    		
    	}
    	
    	@GetMapping(value="testEncryptStringResponse")
    	@ApiOperation(value="测试加密字符串响应信息", notes="测试加密字符串响应信息")
    	@Encrypt
    	public String testEncryptStringResponse(){
    		return "This just a string response encrypt test !";		
    	}
    }
    
  • 用到的DTO信息

    UserInfoDto.java

    /**  
    * Title UserInfoDto.java  
    * Description  
    * @author danyuan
    * @date Nov 29, 2020
    * @version 1.0.0
    * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.framework.demo.popularmvc.controller.dto;
    
    import java.io.Serializable;
    import java.util.List;
    
    import com.danyuanblog.framework.popularmvc.annotation.Encrypt;
    
    import lombok.Data;
    
    @Data
    public class UserInfoDto implements Serializable{/** 
    	 *serialVersionUID
    	 */
    	private static final long serialVersionUID = 1L;
    
    	private String username;
    	private Integer age;
    	@Encrypt
    	private String desc;
    	
    	private List<UserInfoDto> friends;
    }
    

4.2 使用自定义的算法进行加解密

  • 新增自定义加解密算法处理器RSADataEncryptHandler.java

    /**  
    * Title RSADataEncryptHandler.java  
    * Description  
    * @author danyuan
    * @date Jan 4, 2021
    * @version 1.0.0
    * site: www.danyuanblog.com
    */ 
    package com.danyuanblog.framework.demo.popularmvc.component;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import com.danyuanblog.framework.demo.popularmvc.utils.RSAEncryptUtil;
    import com.danyuanblog.framework.popularmvc.SecretManager;
    import com.danyuanblog.framework.popularmvc.consts.ErrorCodes;
    import com.danyuanblog.framework.popularmvc.context.RequestContext;
    import com.danyuanblog.framework.popularmvc.dto.SecretInfo;
    import com.danyuanblog.framework.popularmvc.encrypt.DataEncryptHandler;
    import com.danyuanblog.framework.popularmvc.exception.BusinessException;
    @Component
    public class RSADataEncryptHandler implements DataEncryptHandler {
    
    	@Autowired
    	private SecretManager secretManager;
    	/**
    	 * @author danyuan
    	 */
    	@Override
    	public String encrypt(String appId, String channelId, String userId,
    			String content) throws Throwable {
    		SecretInfo secret = secretManager.load(RequestContext.getContext().getChannelId(), 				
    				RequestContext.getContext().getAppId(), 
    				RequestContext.getContext().getSecretId(), 
    				RequestContext.getContext().getUserId(), 
    				RequestContext.getContext().getSessionId());
    		if(secret != null){
    			return RSAEncryptUtil.encrypt(content, secret.getKeyPair().getPublicSecret());
    		}
    		throw new BusinessException(ErrorCodes.NOT_FOUND_CONFIG).setParam("secret_key");
    	}
    
    	/**
    	 * @author danyuan
    	 */
    	@Override
    	public String decrypt(String appId, String channelId, String userId,
    			String content) throws Throwable {
    		SecretInfo secret = secretManager.load(RequestContext.getContext().getChannelId(), 				
    				RequestContext.getContext().getAppId(), 
    				RequestContext.getContext().getSecretId(), 
    				RequestContext.getContext().getUserId(), 
    				RequestContext.getContext().getSessionId());
    		if(secret != null){
    			return RSAEncryptUtil.decrypt(content, secret.getKeyPair().getPrivateSecret());
    		}
    		throw new BusinessException(ErrorCodes.NOT_FOUND_CONFIG).setParam("secret_key");
    	}
    
    }
    

测试接口源码TestCustomEncryptAndDecryptController.java

/**  
* Title TestCustomEncryptAndDecryptController.java  
* Description  
* @author danyuan
* @date Jan 4, 2021
* @version 1.0.0
* site: www.danyuanblog.com
*/ 
package com.danyuanblog.framework.demo.popularmvc.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.danyuanblog.framework.demo.popularmvc.component.RSADataEncryptHandler;
import com.danyuanblog.framework.demo.popularmvc.controller.dto.UserInfoDto;
import com.danyuanblog.framework.popularmvc.annotation.Decrypt;
import com.danyuanblog.framework.popularmvc.annotation.Encrypt;

@Api(tags = "测试自定义加解密算法的接口数据安全传输功能")
@RestController
@RequestMapping("custom")
public class TestCustomEncryptAndDecryptController {

	@GetMapping(value="testDecryptParamAndResponse",
			name="测试加解密普通参数和响应信息")
	@ApiOperation(value="测试加解密普通参数和响应信息", notes="测试加解密普通参数和响应信息")
	@Encrypt(type = RSADataEncryptHandler.class)
	public UserInfoDto testDecryptParamAndResponse(@RequestParam("desc") @Decrypt(type = RSADataEncryptHandler.class) String desc) {
		UserInfoDto user = new UserInfoDto();
		user.setUsername("danyuan");
		user.setAge(18);
		user.setDesc("this is a encrypt test .");		
		return user;
	}
	
	@GetMapping(value="testEncryptStringResponse")
	@ApiOperation(value="测试加密字符串响应信息", notes="测试加密字符串响应信息")
	@Encrypt(type = RSADataEncryptHandler.class)
	public String testEncryptStringResponse(){
		return "This just a string response encrypt test !";		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值