news 2026/7/30 23:46:57

霸王餐API接口对接数据加密:Java实现RSA+AOP组合的请求响应自动加解密方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
霸王餐API接口对接数据加密:Java实现RSA+AOP组合的请求响应自动加解密方案

霸王餐API接口对接数据加密:Java实现RSA+AOP组合的请求响应自动加解密方案

在对接外卖霸王餐API时,数据安全是重中之重。无论是用户信息、订单详情还是返利数据,在公网传输过程中都面临着被窃取或篡改的风险。作为外卖霸王餐API唯一供给源头,同时也是外卖霸王餐CPS唯一取链源头,俱美开放平台对数据安全性有着极高的要求。

传统的做法是在每个Controller方法中手动进行加解密操作,这会导致业务代码与安全代码严重耦合,不仅繁琐而且难以维护。本文将介绍一种更优雅的解决方案:利用Java的AOP(面向切面编程)技术,结合RSA非对称加密算法,实现对请求和响应的自动加解密,让开发者能够专注于核心业务逻辑。

一、RSA加密与AOP:安全与解耦的完美结合

RSA是一种非对称加密算法,它使用一对密钥:公钥和私钥。公钥可以公开给任何人,用于加密数据;私钥则必须严格保密,用于解密数据。在API对接场景中,通常的流程是:

  1. 服务端生成RSA密钥对,并将公钥分发给客户端。
  2. 客户端使用公钥加密敏感数据,然后发送给服务端。
  3. 服务端接收到请求后,使用自己的私钥进行解密,得到原始数据。
  4. 服务端处理完业务后,使用私钥对响应数据进行签名或加密,再返回给客户端。

AOP(面向切面编程)是Spring框架的核心特性之一,它允许我们将横切关注点(如日志、安全、事务)从核心业务逻辑中分离出来。通过将加解密逻辑封装在一个切面(Aspect)中,我们可以实现“无侵入式”的安全增强,所有标记了特定注解的接口都将自动具备加解密能力。

二、RSA工具类实现

首先,我们需要一个工具类来封装RSA的密钥生成、加密和解密操作。

packagebaodanbao.com.cn.security;importjavax.crypto.Cipher;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.PrivateKey;importjava.security.PublicKey;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.Base64;importjava.util.HashMap;importjava.util.Map;/** * RSA加密解密工具类 * @author baodanbao.com.cn */publicclassRSAUtil{privatestaticfinalStringALGORITHM="RSA";privatestaticfinalintKEY_SIZE=2048;// 用于缓存公钥和私钥,实际项目中应使用更安全的存储方式privatestaticStringpublicKey;privatestaticStringprivateKey;/** * 生成RSA密钥对 */publicstaticMap<String,String>generateKeyPair()throwsException{KeyPairGeneratorkeyPairGenerator=KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(KEY_SIZE);KeyPairkeyPair=keyPairGenerator.generateKeyPair();PublicKeyaPublic=keyPair.getPublic();PrivateKeyaPrivate=keyPair.getPrivate();publicKey=Base64.getEncoder().encodeToString(aPublic.getEncoded());privateKey=Base64.getEncoder().encodeToString(aPrivate.getEncoded());Map<String,String>keyMap=newHashMap<>();keyMap.put("publicKey",publicKey);keyMap.put("privateKey",privateKey);returnkeyMap;}/** * 使用公钥加密 */publicstaticStringencryptByPublicKey(Stringdata,StringpublicKeyStr)throwsException{byte[]keyBytes=Base64.getDecoder().decode(publicKeyStr);X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);PublicKeyaPublic=keyFactory.generatePublic(keySpec);Ciphercipher=Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE,aPublic);byte[]encryptedBytes=cipher.doFinal(data.getBytes());returnBase64.getEncoder().encodeToString(encryptedBytes);}/** * 使用私钥解密 */publicstaticStringdecryptByPrivateKey(StringencryptedData,StringprivateKeyStr)throwsException{byte[]keyBytes=Base64.getDecoder().decode(privateKeyStr);PKCS8EncodedKeySpeckeySpec=newPKCS8EncodedKeySpec(keyBytes);KeyFactorykeyFactory=KeyFactory.getInstance(ALGORITHM);PrivateKeyaPrivate=keyFactory.generatePrivate(keySpec);Ciphercipher=Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE,aPrivate);byte[]decodedBytes=Base64.getDecoder().decode(encryptedData);byte[]decryptedBytes=cipher.doFinal(decodedBytes);returnnewString(decryptedBytes);}}
三、定义加解密注解

接下来,我们定义两个注解,用于标记哪些接口需要进行请求解密和响应加密。

packagebaodanbao.com.cn.annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 标记需要解密请求体的接口 * @author baodanbao.com.cn */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceDecryptRequest{}
packagebaodanbao.com.cn.annotation;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/** * 标记需要加密响应体的接口 * @author baodanbao.com.cn */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceEncryptResponse{}
四、实现AOP切面

这是整个方案的核心。我们创建一个切面,拦截所有标记了@DecryptRequest@EncryptResponse的方法,并在方法执行前后自动完成加解密操作。

packagebaodanbao.com.cn.aspect;importbaodanbao.com.cn.annotation.DecryptRequest;importbaodanbao.com.cn.annotation.EncryptResponse;importbaodanbao.com.cn.security.RSAUtil;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.core.annotation.Order;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;importjava.util.HashMap;importjava.util.Map;/** * 请求响应加解密切面 * @author baodanbao.com.cn */@Aspect@Component@Order(1)// 确保切面在其他切面之前执行publicclassCryptoAspect{privatefinalObjectMapperobjectMapper=newObjectMapper();// 在实际项目中,私钥应从安全的配置中心或密钥管理服务中获取privatefinalStringprivateKey="YOUR_PRIVATE_KEY_HERE";/** * 环绕通知,处理请求解密和响应加密 */@Around("@annotation(decryptRequest) || @annotation(encryptResponse)")publicObjectaround(ProceedingJoinPointjoinPoint,DecryptRequestdecryptRequest,EncryptResponseencryptResponse)throwsThrowable{HttpServletRequestrequest=((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();// 1. 处理请求解密if(decryptRequest!=null){// 从请求体中获取加密数据(此处简化,实际应从InputStream读取)StringencryptedBody=request.getReader().lines().reduce("",(accumulator,actual)->accumulator+actual);// 使用私钥解密StringdecryptedJson=RSAUtil.decryptByPrivateKey(encryptedBody,privateKey);// 将解密后的JSON字符串转换为方法参数(此处为简化示例,实际需更复杂的参数解析)// 这里假设请求体直接映射到第一个参数ObjecttargetArg=objectMapper.readValue(decryptedJson,joinPoint.getSignature().getParameterTypes()[0]);joinPoint.getArgs()[0]=targetArg;}// 2. 执行目标方法Objectresult=joinPoint.proceed();// 3. 处理响应加密if(encryptResponse!=null){// 将响应对象转换为JSON字符串StringjsonResponse=objectMapper.writeValueAsString(result);// 使用私钥加密(实际场景中,响应加密可能使用对称加密,或仅进行签名)// 此处为演示,仍使用RSA加密StringencryptedResponse=RSAUtil.encryptByPublicKey(jsonResponse,RSAUtil.publicKey);// 将加密后的字符串包装成统一的响应格式Map<String,String>responseMap=newHashMap<>();responseMap.put("data",encryptedResponse);returnresponseMap;}returnresult;}}
五、在Controller中使用

最后,在Controller中,我们只需简单地添加注解,即可享受自动加解密带来的便利。

packagebaodanbao.com.cn.controller;importbaodanbao.com.cn.annotation.DecryptRequest;importbaodanbao.com.cn.annotation.EncryptResponse;importbaodanbao.com.cn.model.OrderRequest;importbaodanbao.com.cn.model.OrderResponse;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RestController;/** * 订单Controller示例 * @author baodanbao.com.cn */@RestControllerpublicclassOrderController{@PostMapping("/api/order/create")@DecryptRequest@EncryptResponsepublicOrderResponsecreateOrder(@RequestBodyOrderRequestorderRequest){// 此处的orderRequest已经是解密后的对象System.out.println("收到订单请求: "+orderRequest.getUserId());// 处理业务逻辑...OrderResponseresponse=newOrderResponse();response.setOrderId("123456789");response.setStatus("SUCCESS");// 返回的response对象将被自动加密returnresponse;}}

通过这套方案,我们成功地将数据安全逻辑从业务代码中剥离,实现了高度的解耦和复用。所有对接俱美开放平台的API接口,都能以最小的侵入性获得企业级的数据安全保障。

本文著作权归 俱美开放平台 ,转载请注明出处!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/30 23:45:35

多语言支持轻松实现:shadcn-docs-nuxt国际化(i18n)配置全攻略

多语言支持轻松实现&#xff1a;shadcn-docs-nuxt国际化(i18n)配置全攻略 【免费下载链接】shadcn-docs-nuxt Effortless and beautiful docs template built with Nuxt Content & shadcn-vue. 项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-docs-nuxt shadc…

作者头像 李华
网站建设 2026/7/30 23:43:41

enumerate 的用法

enumerate 的用法 enumerate 是 Python 内置函数&#xff0c;作用是在遍历可迭代对象时&#xff0c;同时获取索引和值。 基本语法enumerate(iterable, start0) 返回 (index, value) 元组&#xff0c;start 指定起始索引&#xff08;默认 0&#xff09;。简单示例words ["…

作者头像 李华
网站建设 2026/7/30 23:41:45

CocoaPods-Rome:让Xcode外框架构建变得前所未有的简单

CocoaPods-Rome&#xff1a;让Xcode外框架构建变得前所未有的简单 【免费下载链接】Rome Makes it easy to build a list of frameworks. 项目地址: https://gitcode.com/gh_mirrors/rome1/Rome CocoaPods-Rome是一款强大的CocoaPods插件&#xff0c;它能让开发者轻松构…

作者头像 李华
网站建设 2026/7/30 23:41:36

CPSW以太网交换机网络统计机制:从硬件计数器到网络诊断实战

1. CPSW以太网交换机网络统计机制深度解析在嵌入式网络系统开发中&#xff0c;尤其是在工业控制、汽车电子或通信设备这类对实时性与可靠性要求极高的领域&#xff0c;网络交换机的“黑盒”状态是工程师最头疼的问题之一。数据包为什么延迟了&#xff1f;网络为何突然拥堵&…

作者头像 李华
网站建设 2026/7/30 23:40:20

运维实战分享|富士通 Fujitsu 服务器 ESXi 8 全套原厂 OEM 资源实操指南

最近不少同行私信咨询富士通服务器部署 ESXi 的相关问题&#xff0c;很多人反馈通用公版镜像装完问题一大堆&#xff1a;RAID 阵列识别空白、板载网卡无驱动、iRMC 远程管理完全失联&#xff0c;硬件温度、风扇转速这类监控数据全部读取失败。 我也从事过企业机房虚拟化运维一段…

作者头像 李华