# field-spring-boot-starter-encrypt **Repository Path**: leileispace/field-spring-boot-starter-encrypt ## Basic Information - **Project Name**: field-spring-boot-starter-encrypt - **Description**: DB字段加解密 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-05-21 - **Last Updated**: 2025-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Field Spring Boot Starter Encrypt 一个基于 Spring Boot 的字段加解密 Starter,提供数据库字段加密/解密和 Web 参数解密功能。 ## 📋 功能特性 ### 1. 数据库字段加密/解密(SM4) - ✅ 基于 MyBatis-Plus 拦截器实现 - ✅ 支持插入/更新时自动加密 - ✅ 支持查询时自动解密 - ✅ 支持 HEX 和 BASE64 两种编码格式 - ✅ 可配置加密前缀标识 - ✅ 使用 `@EncryptField` 注解标记需要加密的字段 ### 2. Web 参数解密(SM2) - ✅ **整个请求体解密**:使用 `@WebDecryptBody` 注解,适用于整个 JSON 字符串加密的场景 - ✅ **字段级别解密**:使用 `@WebDecryptField` 注解,适用于部分字段加密的场景 - ✅ 两种解密模式可独立启用,互不干扰 - ✅ 支持日志开关配置,便于调试 - ✅ 支持密文前缀自动添加(04 前缀) ## 🔧 依赖要求 - JDK 1.8+ - Spring Boot 2.3.5+ - MyBatis-Plus 3.5.2+(数据库加密功能需要) - Spring Web(Web 解密功能需要) ## 📦 Maven 依赖 ```xml com.leilei field-spring-boot-starter-encrypt 1.0.2 ``` ## 🚀 快速开始 ### 1. 数据库字段加密/解密(SM4) #### 1.1 配置 在 `application.yml` 或 `application.properties` 中配置: ```yaml field-encrypt: enabled: true # 是否启用,默认 true sm4-key: your-16-byte-key # SM4 密钥(16字节) encrypt-type: SM4BASE64 # 加密类型:SM4HEX 或 SM4BASE64 encrypt-prefix: Enc_ # 加密前缀标识,默认 Enc_ ``` #### 1.2 使用 在实体类的字段上添加 `@EncryptField` 注解: ```java import com.leilei.db.EncryptField; public class User { private Long id; @EncryptField private String phone; // 该字段会自动加密/解密 @EncryptField private String email; // 该字段会自动加密/解密 private String name; // 该字段不会加密 } ``` #### 1.3 工作原理 - **加密时机**:执行 `INSERT` 或 `UPDATE` 操作时,标记了 `@EncryptField` 的字段会自动加密 - **解密时机**:执行 `SELECT` 查询时,标记了 `@EncryptField` 的字段会自动解密 - **加密格式**:密文会添加配置的前缀(如 `Enc_`),便于识别 ### 2. Web 参数解密(SM2) model为C1C3C2 #### 2.1 配置 在 `application.yml` 或 `application.properties` 中配置: ```yaml web-decrypt: # 整个请求体解密配置 body-decrypt-enabled: true # 是否启用整个请求体解密 body-decrypt-log-enabled: false # 是否打印请求体解密日志(调试用) # 字段级别解密配置 field-decrypt-enabled: true # 是否启用字段级别解密 field-decrypt-log-enabled: false # 是否打印字段解密日志(调试用) # SM2 密钥配置 sm2-private-key: your-private-key # SM2 私钥(必填) sm2-public-key: your-public-key # SM2 公钥(可选) # 其他配置 append04: true # 是否在解密时添加 04 前缀(有时前端加密后的数据,要解密必须拼接04,此时加解密秘钥使用 Q D值) ``` #### 2.2 方式一:整个请求体解密 适用于前端将整个 JSON 字符串加密后传输的场景。 **在 Controller 上使用:** ```java import com.leilei.web.WebDecryptBody; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @WebDecryptBody // 该类下所有 @RequestBody 参数都会自动解密 public class UserController { @PostMapping("/user") public String createUser(@RequestBody UserDTO user) { // user 对象已经是解密后的数据 return "success"; } } ``` **在方法上使用:** ```java @RestController public class UserController { @PostMapping("/user") @WebDecryptBody // 仅该方法中的 @RequestBody 参数会解密 public String createUser(@RequestBody UserDTO user) { // user 对象已经是解密后的数据 return "success"; } } ``` **在参数上使用:** ```java @RestController public class UserController { @PostMapping("/user") public String createUser(@WebDecryptBody @RequestBody UserDTO user) { // user 对象已经是解密后的数据 return "success"; } } ``` #### 2.3 方式二:字段级别解密 适用于只有部分字段加密,其他字段明文的场景。 **在 DTO 类的字段上使用:** ```java import com.leilei.web.WebDecryptField; public class UserDTO { private String name; // 明文字段 @WebDecryptField // 该字段会自动解密 private String phone; // 加密字段 @WebDecryptField // 该字段会自动解密 private String email; // 加密字段 private Integer age; // 明文字段 } ``` **Controller 使用:** ```java @RestController public class UserController { @PostMapping("/user") public String createUser(@RequestBody UserDTO user) { // user.phone 和 user.email 已经是解密后的数据 // user.name 和 user.age 保持原样 return "success"; } } ``` #### 2.4 注意事项 ⚠️ **重要**:`@WebDecryptBody` 和 `@WebDecryptField` **不能在同一接口中混用**,请根据实际场景选择其中一种方式。 ## 📝 配置说明 ### 数据库字段加密配置(field-encrypt) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `field-encrypt.enabled` | boolean | `true` | 是否启用数据库字段加解密 | | `field-encrypt.sm4-key` | String | - | SM4 密钥(16字节),必填 | | `field-encrypt.encrypt-type` | Enum | `SM4BASE64` | 加密类型:`SM4HEX` 或 `SM4BASE64` | | `field-encrypt.encrypt-prefix` | String | `Enc_` | 加密前缀标识 | ### Web 参数解密配置(web-decrypt) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `web-decrypt.body-decrypt-enabled` | boolean | `false` | 是否启用整个请求体解密 | | `web-decrypt.field-decrypt-enabled` | boolean | `false` | 是否启用字段级别解密 | | `web-decrypt.body-decrypt-log-enabled` | boolean | `false` | 是否打印请求体解密日志 | | `web-decrypt.field-decrypt-log-enabled` | boolean | `false` | 是否打印字段解密日志 | | `web-decrypt.sm2-private-key` | String | - | SM2 私钥,必填 | | `web-decrypt.sm2-public-key` | String | - | SM2 公钥(可选) | | `web-decrypt.append04` | boolean | `true` | 是否在解密时添加 04 前缀 | ## 💡 使用示例 ### 完整示例:数据库字段加密 ```java // 1. 实体类 @Entity @Table(name = "user") public class User { private Long id; @EncryptField private String phone; @EncryptField private String email; private String name; } // 2. Service 层正常使用 @Service public class UserService { @Autowired private UserMapper userMapper; public void saveUser(User user) { // 插入时,phone 和 email 会自动加密 userMapper.insert(user); } public User getUserById(Long id) { // 查询时,phone 和 email 会自动解密 return userMapper.selectById(id); } } ``` ### 完整示例:Web 参数解密 ```java // 1. DTO 类(字段级别解密) public class LoginDTO { private String username; @WebDecryptField private String password; // 该字段会被自动解密 } // 2. Controller @RestController public class AuthController { @PostMapping("/login") public Result login(@RequestBody LoginDTO loginDTO) { // loginDTO.password 已经是解密后的数据 // 可以直接用于验证 return Result.success(); } } // 或者使用整个请求体解密 @RestController @WebDecryptBody public class AuthController { @PostMapping("/login") public Result login(@RequestBody LoginDTO loginDTO) { // 整个请求体都会被解密 return Result.success(); } } ``` ## ⚠️ 注意事项 1. **密钥安全**:请妥善保管 SM4 和 SM2 密钥,不要将密钥提交到代码仓库 2. **性能考虑**:加解密操作会带来一定的性能开销,建议只对敏感字段进行加密 3. **兼容性**:已加密的数据需要保持密钥和配置一致,否则无法正确解密 4. **日志安全**:开启日志开关时,注意日志中可能包含敏感信息,生产环境建议关闭 5. **混用限制**:`@WebDecryptBody` 和 `@WebDecryptField` 不能在同一接口中混用 6. **字段类型**:`@EncryptField` 和 `@WebDecryptField` 仅支持 `String` 类型字段 ## 🔍 故障排查 ### 数据库加密不生效 - 检查 `field-encrypt.enabled` 是否为 `true` - 检查 `field-encrypt.sm4-key` 是否配置 - 检查实体类字段是否添加了 `@EncryptField` 注解 - 检查字段类型是否为 `String` ### Web 解密不生效 - 检查 `web-decrypt.body-decrypt-enabled` 或 `web-decrypt.field-decrypt-enabled` 是否为 `true` - 检查 `web-decrypt.sm2-private-key` 是否配置 - 检查注解是否正确添加(`@WebDecryptBody` 或 `@WebDecryptField`) - 检查是否引入了 `spring-boot-starter-web` 依赖 - 查看启动日志,确认相关 Bean 是否加载成功 ### 解密失败 - 检查密钥是否正确 - 检查密文格式是否正确(是否需要添加 04 前缀) - 检查前后端加密/解密算法是否一致 - 开启日志开关查看详细错误信息 ## 📄 许可证 本项目采用 MIT 许可证。 ## 👤 作者 lei ## 📅 更新日志 ### v1.0.2 - 新增 SM2 Web 参数解密功能 - 支持整个请求体解密和字段级别解密两种模式 - 新增日志开关配置 - 优化代码结构和注释 ### v1.0.1 - 初始版本 - 支持 SM4 数据库字段加密/解密