# api-encrypt-spring-boot-starter **Repository Path**: zhangyizhou/api-encrypt-spring-boot-starter ## Basic Information - **Project Name**: api-encrypt-spring-boot-starter - **Description**: 基于 Spring Boot 的 API 数据加解密组件 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-15 - **Last Updated**: 2026-10-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # API Encrypt Spring Boot Starter 使用手册 ## 📖 简介 `api-encrypt-spring-boot-starter` 是一个基于 Spring Boot 的 API 数据加解密组件,提供透明的请求解密和响应加密功能。支持 GET 请求参数解密、POST 请求体解密以及响应数据加密,帮助开发者快速实现 API 数据传输加密。 ### 核心特性 - ✅ **透明加解密**:基于 Spring MVC 的 Advice 和 Filter 机制,对业务代码无侵入 - ✅ **GET/POST 支持**:自动处理 GET 查询参数和 POST 请求体的解密 - ✅ **响应加密**:自动加密响应数据中的 `data` 字段 - ✅ **灵活配置**:通过配置文件一键开关,支持多种 AES 密钥长度 - ✅ **Spring Boot 自动装配**:引入依赖即可使用,零配置启动 --- ## 🚀 快速开始 ### 1. 环境要求 - Java 8 或以上版本 - Spring Boot 2.7.x(推荐 2.7.18) - Maven 3.5+ ### 2. 添加依赖 在你的 Spring Boot 项目的 `pom.xml` 中添加依赖: ```xml com.iminggu api-encrypt-spring-boot-starter 1.0.0 ``` ### 3. 配置密钥 在 `application.yml` 或 `application.properties` 中配置加密开关和密钥: **application.yml 方式:** ```yaml api: encrypt: enabled: true secret-key: "your-base64-encoded-secret-key" ``` **application.properties 方式:** ```properties api.encrypt.enabled=true api.encrypt.secret-key=your-base64-encoded-secret-key ``` ### 4. 生成密钥 密钥必须是 Base64 编码的 AES 密钥,支持以下三种长度: | AES 类型 | 原始密钥长度 | Base64 编码后长度 | 示例 | |---------|------------|----------------|------| | AES-128 | 16 字节 | 24 字符 | `d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9` | | AES-192 | 24 字节 | 32 字符 | `d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9d4f3c2b1a0e9d8c7` | | AES-256 | 32 字节 | 44 字符 | `d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9` | **使用 Hutool 生成密钥示例:** ```java import cn.hutool.core.codec.Base64; import cn.hutool.crypto.SecureUtil; public class KeyGenerator { public static void main(String[] args) { // 生成 AES-256 密钥(32字节) byte[] key = SecureUtil.generateKey("AES", 256).getEncoded(); String base64Key = Base64.encode(key); System.out.println("Base64密钥: " + base64Key); } } ``` --- ## 📋 使用说明 ### 响应数据格式 组件要求响应数据使用 `EncryptResult` 格式,会自动加密其中的 `data` 字段: ```java import com.iminggu.common.EncryptResult; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api") public class UserController { @GetMapping("/user/{id}") public EncryptResult getUser(@PathVariable Long id) { User user = userService.getById(id); // data 字段会被自动加密 return EncryptResult.data(user); } @PostMapping("/user") public EncryptResult createUser(@RequestBody User user) { userService.save(user); return EncryptResult.ok("创建成功"); } } ``` **EncryptResult 常用方法:** ```java // 成功响应(带数据) EncryptResult.data(userObject); // 成功响应(带消息) EncryptResult.ok("操作成功"); // 成功响应(无参数) EncryptResult.ok(); // 错误响应 EncryptResult.error("操作失败"); // 未登录响应 EncryptResult.notLogin(); // 无权限响应 EncryptResult.notPermission(); // 自定义状态码 EncryptResult.get(200, "自定义消息", dataObject); ``` ### 请求数据格式 #### POST 请求(自动解密) 客户端发送加密的 JSON 数据到 POST 请求体: ```http POST /api/user HTTP/1.1 Content-Type: application/json <加密后的Base64字符串> ``` 服务端 Controller 正常接收: ```java @PostMapping("/user") public EncryptResult createUser(@RequestBody User user) { // user 对象已被自动解密并反序列化 // 业务代码无需处理解密逻辑 userService.save(user); return EncryptResult.ok(); } ``` #### GET 请求(自动解密) 客户端发送加密的查询参数: ```http GET /api/user?encryptedParams HTTP/1.1 ``` 其中 `encryptedParams` 是加密后的查询字符串,例如:`name=张三&age=25` 加密后的 Base64 字符串。 服务端 Controller 正常接收参数: ```java @GetMapping("/user") public EncryptResult getUser(@RequestParam String name, @RequestParam Integer age) { // name 和 age 参数已被自动解密 User user = userService.getByNameAndAge(name, age); return EncryptResult.data(user); } ``` --- ## ⚙️ 配置说明 ### 配置项列表 | 配置项 | 类型 | 必填 | 默认值 | 说明 | |-------|------|------|--------|------| | `api.encrypt.enabled` | boolean | 否 | `false` | 是否启用加密功能 | | `api.encrypt.secret-key` | String | 是* | 无 | AES 密钥(Base64 编码),启用加密时必填 | ### 配置示例 **开发环境(不启用加密):** ```yaml api: encrypt: enabled: false ``` **生产环境(启用加密):** ```yaml api: encrypt: enabled: true secret-key: "d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9d4f3c2b1a0e9d8c7b6a5f4e3d2c1b0a9" ``` --- ## 🔧 工作原理 ### 整体架构 ``` 客户端请求 ↓ [DecryptGetRequestFilter] → 解密 GET 请求参数 ↓ [DecryptRequestBodyAdvice] → 解密 POST 请求体 ↓ Controller 处理业务 ↓ [EncryptResponseBodyAdvice] → 加密响应数据 ↓ 返回客户端 ``` ### 核心组件 1. **DecryptGetRequestFilter**:Servlet 过滤器,拦截 GET 请求并解密查询参数 2. **DecryptRequestBodyAdvice**:Spring MVC 拦截器,解密 POST 请求体 3. **EncryptResponseBodyAdvice**:Spring MVC 拦截器,加密响应数据 4. **ApiEncryptionService**:加解密服务,提供统一的 AES 加解密方法 5. **ApiEncryptAutoConfiguration**:Spring Boot 自动配置类 ### 数据流向 **请求解密流程:** ``` 加密数据(Base64) → AES解密 → 原始JSON/查询字符串 → 业务代码 ``` **响应加密流程:** ``` 业务数据 → 转为JSON → AES加密 → Base64编码 → 客户端 ``` --- ## 📝 完整示例 ### 服务端示例 ```java import com.iminggu.common.EncryptResult; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api") public class DemoController { /** * GET 请求示例 * 客户端需要发送加密后的查询参数 */ @GetMapping("/hello") public EncryptResult hello(@RequestParam String name) { return EncryptResult.data("Hello, " + name); } /** * POST 请求示例 * 客户端需要发送加密后的 JSON 数据 */ @PostMapping("/echo") public EncryptResult echo(@RequestBody Message message) { return EncryptResult.data("收到: " + message.getContent()); } } ``` ### 客户端示例(Java) ```java import cn.hutool.core.codec.Base64; import cn.hutool.crypto.SecureUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; public class ApiClient { private static final String SECRET_KEY = "your-base64-encoded-secret-key"; private static final String BASE_URL = "http://localhost:8080/api"; /** * 加密数据 */ public static String encrypt(String data) { byte[] keyBytes = Base64.decode(SECRET_KEY); byte[] encrypted = SecureUtil.aes(keyBytes).encrypt(data); return Base64.encode(encrypted); } /** * 解密数据 */ public static String decrypt(String encryptedData) { byte[] keyBytes = Base64.decode(SECRET_KEY); byte[] decoded = Base64.decode(encryptedData); byte[] decrypted = SecureUtil.aes(keyBytes).decrypt(decoded); return new String(decrypted); } /** * 调用 GET 接口 */ public static void testGet() { // 加密查询参数 String queryParams = "name=张三"; String encryptedParams = encrypt(queryParams); // 发送请求 String response = HttpUtil.get(BASE_URL + "/hello?" + encryptedParams); System.out.println("响应: " + response); // 解析并解密响应 EncryptResult result = JSONUtil.toBean(response, EncryptResult.class); String decryptedData = decrypt(result.getData().toString()); System.out.println("解密后: " + decryptedData); } /** * 调用 POST 接口 */ public static void testPost() { // 准备数据 Message message = new Message(); message.setContent("Hello World"); String jsonData = JSONUtil.toJsonStr(message); // 加密请求体 String encryptedBody = encrypt(jsonData); // 发送请求 String response = HttpUtil.post(BASE_URL + "/echo", encryptedBody); System.out.println("响应: " + response); // 解析并解密响应 EncryptResult result = JSONUtil.toBean(response, EncryptResult.class); String decryptedData = decrypt(result.getData().toString()); System.out.println("解密后: " + decryptedData); } } ``` --- ## 🔍 调试技巧 ### 开启调试日志 在 `application.yml` 中设置日志级别: ```yaml logging: level: com.iminggu: debug ``` 开启后会输出以下调试信息: - 请求体解密前后的数据 - 响应数据加密前后的数据 - GET 请求参数解密信息 ### 常见问题排查 **问题1:启动时报"未配置API加密密钥"** - 检查 `api.encrypt.enabled` 是否为 `true` - 检查 `api.encrypt.secret-key` 是否已配置 - 确认密钥是有效的 Base64 编码字符串 **问题2:启动时报"AES密钥长度无效"** - 确认密钥 Base64 解码后是 16、24 或 32 字节 - 使用上面提供的密钥生成工具重新生成 **问题3:请求解密失败** - 确认客户端使用的密钥与服务端一致 - 确认客户端加密后的数据是 Base64 编码 - 检查请求 Content-Type 是否正确 **问题4:响应数据未加密** - 确认返回类型是 `EncryptResult` - 确认 `data` 字段不为 null - 检查 `api.encrypt.enabled` 是否为 `true` --- ## ⚠️ 注意事项 1. **密钥安全**: - 生产环境建议使用环境变量或配置中心管理密钥 - 不要将密钥硬编码在配置文件中提交到版本控制系统 2. **性能考虑**: - 加密/解密会增加一定的 CPU 开销 - 对于大数据量的接口,建议评估性能影响 3. **兼容性**: - 仅对使用 `EncryptResult` 返回的接口生效 - GET 和 POST 请求会自动解密,无需额外配置 4. **异常处理**: - 解密失败时会抛出异常,客户端会收到 400 错误 - 响应加密失败时会返回原始数据(不加密) --- ## 📦 依赖说明 项目使用的主要依赖: | 依赖 | 版本 | 用途 | |-----|------|------| | spring-boot-starter-web | 2.7.18 | Spring MVC 支持 | | hutool-all | 5.8.25 | 加密工具类 | | lombok | - | 简化代码 | --- ## 🤝 贡献与反馈 如有问题或建议,欢迎反馈。 --- ## 📄 License MIT License --- **最后更新时间:** 2026-04-15