一、背景
项目采用RuoYi前后端分离框架搭建,版本为3.8.9。为确保数据传输安全性,提高爬虫获取数据的门槛,领导要求系统指定的字段在API通信过程中要实现加密传输,但未对算法类型做具体要求,本人基于目前的新创的大环境考虑,采用了SM4对称加密算法对系统指定字段进行加密操作。
二、设计思路
在基于RuoYi前后端框架进行实现时,本人主要考虑了:
- 第一,未来领导要求用其他加密算法进行加密时,不用改动原有加密实现的整体框架,只需要新增领导指定的加密算法的加解密实现即可
- 第二、要能方便的进行加解密算法的自定义切换
- 第三、要采用spring框架提供的开放接口进行优雅的集成
话不多说,直接开整。
三、加解密标记注解
主要有API接口请求/响应标记注解和加解密目标字段标记注解,前者提供对请求/响应加解密的标记,后者实现对加解密目标字段的标记。
-
1.目标字段标记注解:EncryptedField
package com.book.common.annotation.encrypt; import java.lang.annotation.*; /** * @className: EncryptedField * @author: liuyh * @date: 2025/5/20 15:56 * @Version: 1.0 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EncryptedField { // String value() default "SM4"; // 默认使用 SM4 加密 }
-
2.API请求解密标记注解:EncryptedRequest
package com.book.common.annotation.encrypt; import java.lang.annotation.*; /** * @className: EncryptedRequest * @author: liuyh * @date: 2025/5/20 10:09 * @Version: 1.0 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EncryptedRequest { String value() default "SM4"; // 默认使用 SM4 加密 }
-
3.API响应加密标记注解:EncryptedResponse
package com.book.common.annotation.encrypt; import java.lang.annotation.*; /** * @className: EncryptedRequest * @author: liuyh * @date: 2025/5/20 10:09 * @Version: 1.0 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface EncryptedResponse { String value() default "SM4"; // 默认使用 SM4 加密 }
四、加解密器实现
加解密器,采用了工厂模式,说是工厂模式,其实就是一个加解密实现类实例协调器(映射工厂)。
-
1.添加SM轮子
<dependency> <groupId>com.antherd</groupId> <artifactId>sm-crypto</artifactId> <version>0.3.2.1</version> </dependency>
-
2.加解密器接口类
package com.book.framework.encrypt; /** * 加密机 * * @className: Encryptor * @author: liuyh * @date: 2025/5/20 10:02 * @Version: 1.0 */ public interface Encryptor { /** * 加密 * * @param content * @return */ String encrypt(String content); /** * 解密 * * @param cipherText * @return */ String decrypt(String cipherText); }
-
3.加解密器工厂类
package com.book.framework.encrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* 加密工厂类
*
* @className: EncryptorFactory
* @author: liuyh
* @date: 2025/5/20 10:36
* @Version: 1.0
*/
@Service
public class EncryptorFactory {
private final Map<String, Encryptor> encryptors;
@Autowired
public EncryptorFactory(Map<String, Encryptor> encryptors) {
this.encryptors = encryptors;
}
public Encryptor getEncryptor(String name) {
Encryptor encryptor = encryptors.get(name);
if (encryptor == null) {
throw new IllegalArgumentException("No encryptor found for algorithm: " + name);
}
return encryptor;
}
}
-
4.SM4算法实现
package com.book.framework.encrypt; import com.antherd.smcrypto.sm4.Sm4; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotat