该抽象类中提供了2中对称加密的密钥还原 , 分表是AES和DES算法 。一个抽象方法 , 该抽象方法
keySpec该方法需要子类实现(具体使用的是哪种对称加密算法) 。
具体加密算法的实现类
AESAlgorithmpublic class AESAlgorithm extends AbstractSecretProcess {@Overridepublic String getAlgorithm() {return "AES/ECB/PKCS5Padding";}@Overridepublic Key keySpec() {return this.getKeySpec("AES") ;}}SecretProperties@Configurationpublic class SecretConfig {@Bean@ConditionalOnMissingBean(SecretProcess.class)public SecretProcess secretProcess() {return new AESAlgorithm() ;}@Component@ConfigurationProperties(prefix = "secret")public static class SecretProperties {private Boolean enabled ;private String key ;public Boolean getEnabled() {return enabled;}public void setEnabled(Boolean enabled) {this.enabled = enabled;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}}}配置文件中如下配置:
secret:key: aaaabbbbccccdddd #密钥enabled: true #是否开启加解密功能在项目中可能不是所有的方法都要进行数据的加密解密出来 , 所以接下来定义一个注解 , 只有添加有该注解的Controller类或是具体接口方法才进行数据的加密解密 , 如下:
SIProtection@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Mapping@Documentedpublic @interface SIProtection {}对请求内容进行解密出来 , 通过RequestBodyAdvice
DecryptRequestBodyAdivce@ControllerAdvice@ConditionalOnProperty(name = "secret.enabled", havingValue = https://www.isolves.com/it/cxkf/bk/2023-08-28/"true")public class DecryptRequestBodyAdivce extends RequestBodyAdviceAdapter {@Resourceprivate SecretProcess secretProcess ;@Overridepublic boolean supports(MethodParameter methodParameter, Type targetType,Class extends HttpMessageConverter>> converterType) {return methodParameter.getMethod().isAnnotationPresent(SIProtection.class)|| methodParameter.getMethod().getDeclaringClass().isAnnotationPresent(SIProtection.class) ;}@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,Class extends HttpMessageConverter>> converterType) throws IOException {String body = secretProcess.decrypt(inToString(inputMessage.getBody())) ;return new HttpInputMessage() {@Overridepublic HttpHeaders getHeaders() {return inputMessage.getHeaders();}@Overridepublic InputStream getBody() throws IOException {return new ByteArrayInputStream(body.getBytes()) ;}} ;}private String inToString(InputStream is) {byte[] buf = new byte[10 * 1024] ;int leng = -1 ;StringBuilder sb = new StringBuilder() ;try {while ((leng = is.read(buf)) != -1) {sb.append(new String(buf, 0, leng)) ;}return sb.toString() ;} catch (IOException e) {throw new RuntimeException(e) ;}}}注意这里的:@ConditionalOnProperty(name = "secret.enabled", havingValue = https://www.isolves.com/it/cxkf/bk/2023-08-28/"true")注解 , 只有开启了加解密功能才会生效 。注意这里的supports方法
对响应内容加密出来
EncryptResponseBodyAdivce@ControllerAdvice@ConditionalOnProperty(name = "secret.enabled", havingValue = https://www.isolves.com/it/cxkf/bk/2023-08-28/"true")public class EncryptResponseBodyAdivce implements ResponseBodyAdviceController接口@PostMapping("/save")@SIProtectionpublic R save(@RequestBody Users users) {return R.success(usersService.save(users)) ;} // 这对具体方法进行加解密@RestController@RequestMapping("/users")@SIProtection public class UsersController { // 对该Controller中的所有方法进行加解密处理}前端
引入第三方插件:crypto-js
工具方法加解密:
/** * 加密方法 * @param data 待加密数据 * @returns {string|*} */encrypt (data) {let key = CryptoJS.enc.Utf8.parse(Consts.Secret.key)if (typeof data =https://www.isolves.com/it/cxkf/bk/2023-08-28/== 'object') {data = JSON.stringify(data)}let plAInText = CryptoJS.enc.Utf8.parse(data)let secretText = CryptoJS.AES.encrypt(plainText, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}).ciphertext.toString()return secretText},/** * 解密数据 * @param data 待解密数据 */decrypt (data) {let key = CryptoJS.enc.Utf8.parse(Consts.Secret.key)let secretText = CryptoJS.enc.Hex.parse(data)let encryptedBase64Str = CryptoJS.enc.Base64.stringify(secretText)let result = CryptoJS.AES.decrypt(encryptedBase64Str, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8)return JSON.parse(result)}
推荐阅读
- 容器技术架构、网络和生态详解
- 什么是小跑铅钓法?小跑铅钓法详解
- TypeScript接口与类 - 类型系统高级用法
- SpringBoot项目中异步调用接口方式知多少?
- Redis干货 | 五种常用类型之Hash哈希存储类型详解
- SpringBoot通过一个注解结合Redis实现接口限流就是这么简单
- MySQL算术运算符使用详解
- MySQL逻辑运算符使用详解
- 水草造景教程 水草造景教程详解
- tpc接口和普通接口的区别 tpc接口是什么
