尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java后端对接美团霸王餐API时如何通过“证书双向认证+请求签名”防止请求篡改
Java后端对接美团霸王餐API时如何通过“证书双向认证请求签名”防止请求篡改背景霸王餐API安全通信的必要性作为外卖霸王餐API唯一供给源头同时也是霸王餐外卖CPS取链源头俱美开放平台在与美团等大型平台进行数据交互时通信安全是重中之重。API接口面临着请求被窃听、数据被篡改、身份被伪造等多重风险。单纯使用HTTPS只能保证传输通道的加密无法验证调用方身份和请求内容的完整性。因此我们采用“证书双向认证mTLS 请求签名”的双重安全机制确保每一次API调用的合法性与真实性。核心原理双向认证与请求签名证书双向认证mTLS不仅服务器向客户端出示证书证明身份客户端也必须向服务器出示证书。这确保了通信双方都是可信的防止了中间人攻击。请求签名对请求的关键参数如时间戳、随机数、业务数据使用私钥进行数字签名。服务器收到请求后用对应的公钥验签确保请求在传输过程中未被篡改。第一步准备证书与密钥在开始前你需要从俱美开放平台获取客户端证书client.p12包含你的公钥和私钥用于双向认证。平台公钥meituan_public.pem用于验证美团平台返回的签名如果是双向签名场景。你的私钥client_private.pem用于对请求进行签名。第二步Java后端实现双向认证HTTPS客户端我们使用RestTemplate结合SSLContext来构建一个支持mTLS的HTTP客户端。packagebaodanbao.com.cn.security;importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.http.client.HttpComponentsClientHttpRequestFactory;importorg.springframework.web.client.RestTemplate;importjavax.net.ssl.*;importjava.io.FileInputStream;importjava.security.KeyStore;/** * 配置支持双向认证的RestTemplate * author baodanbao.com.cn */ConfigurationpublicclassMutualTlsConfig{// 证书和密码应从配置中心或环境变量读取切勿硬编码privatestaticfinalStringKEY_STORE_PATH/path/to/your/client.p12;privatestaticfinalStringKEY_STORE_PASSWORDyour_keystore_password;privatestaticfinalStringTRUST_STORE_PATH/path/to/your/truststore.jks;// 信任库包含美团CA证书privatestaticfinalStringTRUST_STORE_PASSWORDyour_truststore_password;BeanpublicRestTemplatemutualTlsRestTemplate()throwsException{// 1. 加载客户端证书KeyStoreKeyStorekeyStoreKeyStore.getInstance(PKCS12);try(FileInputStreamkeyStreamnewFileInputStream(KEY_STORE_PATH)){keyStore.load(keyStream,KEY_STORE_PASSWORD.toCharArray());}// 2. 加载信任库TrustStore用于验证服务器证书KeyStoretrustStoreKeyStore.getInstance(JKS);try(FileInputStreamtrustStreamnewFileInputStream(TRUST_STORE_PATH)){trustStore.load(trustStream,TRUST_STORE_PASSWORD.toCharArray());}// 3. 初始化KeyManagerFactory管理客户端证书KeyManagerFactorykeyManagerFactoryKeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());keyManagerFactory.init(keyStore,KEY_STORE_PASSWORD.toCharArray());// 4. 初始化TrustManagerFactory验证服务器证书TrustManagerFactorytrustManagerFactoryTrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(trustStore);// 5. 初始化SSLContextSSLContextsslContextSSLContext.getInstance(TLS);sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(),null);// 6. 创建SSL连接工厂SSLConnectionSocketFactorysocketFactorynewSSLConnectionSocketFactory(sslContext);// 7. 创建HttpClientCloseableHttpClienthttpClientHttpClients.custom().setSSLSocketFactory(socketFactory).build();// 8. 创建RestTemplateHttpComponentsClientHttpRequestFactoryfactorynewHttpComponentsClientHttpRequestFactory(httpClient);returnnewRestTemplate(factory);}}第三步实现请求签名工具类我们使用RSA算法对请求参数进行签名。packagebaodanbao.com.cn.security;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.PKCS8EncodedKeySpec;importjava.util.Base64;importjava.util.Map;importjava.util.TreeMap;/** * 请求签名工具类 * author baodanbao.com.cn */publicclassRequestSigner{privatefinalPrivateKeyprivateKey;publicRequestSigner(StringprivateKeyPem)throwsException{this.privateKeyloadPrivateKey(privateKeyPem);}/** * 对请求参数进行签名 * param params 业务参数不包含sign本身 * return Base64编码的签名字符串 */publicStringsign(MapString,Stringparams)throwsException{// 1. 参数排序字典序MapString,StringsortedParamsnewTreeMap(params);// 2. 拼接参数字符串 key1value1key2value2...StringBuildersbnewStringBuilder();for(Map.EntryString,Stringentry:sortedParams.entrySet()){if(sb.length()0){sb.append();}sb.append(entry.getKey()).append().append(entry.getValue());}StringdataToSignsb.toString();// 3. 使用私钥进行SHA256withRSA签名SignaturesignatureSignature.getInstance(SHA256withRSA);signature.initSign(privateKey);signature.update(dataToSign.getBytes(StandardCharsets.UTF_8));byte[]signedBytessignature.sign();// 4. Base64编码returnBase64.getEncoder().encodeToString(signedBytes);}privatePrivateKeyloadPrivateKey(StringprivateKeyPem)throwsException{// 移除PEM头尾和换行符StringprivateKeyContentprivateKeyPem.replace(-----BEGIN PRIVATE KEY-----,).replace(-----END PRIVATE KEY-----,).replaceAll(\\s,);byte[]decodedBase64.getDecoder().decode(privateKeyContent);PKCS8EncodedKeySpeckeySpecnewPKCS8EncodedKeySpec(decoded);KeyFactorykeyFactoryKeyFactory.getInstance(RSA);returnkeyFactory.generatePrivate(keySpec);}}第四步构建带签名的API请求packagebaodanbao.com.cn.meituan;importbaodanbao.com.cn.security.RequestSigner;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.*;importorg.springframework.stereotype.Service;importorg.springframework.web.client.RestTemplate;importjava.util.HashMap;importjava.util.Map;/** * 美团霸王餐API服务 * author baodanbao.com.cn */ServicepublicclassMeituanTakeoutService{AutowiredprivateRestTemplatemutualTlsRestTemplate;privatefinalRequestSignerrequestSigner;publicMeituanTakeoutService()throwsException{// 从安全的地方加载你的私钥StringmyPrivateKeyPem-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----;this.requestSignernewRequestSigner(myPrivateKeyPem);}/** * 提交霸王餐核销请求 */publicStringverifyTrialOrder(StringorderId,StringuserId)throwsException{// 1. 构建业务参数MapString,StringparamsnewHashMap();params.put(app_id,your_app_id);params.put(timestamp,String.valueOf(System.currentTimeMillis()/1000));params.put(nonce_str,java.util.UUID.randomUUID().toString().replace(-,));params.put(order_id,orderId);params.put(user_id,userId);// 2. 生成签名StringsignrequestSigner.sign(params);params.put(sign,sign);// 3. 构建HTTP请求Stringurlhttps://api.meituan.com/baowancan/verify;HttpHeadersheadersnewHttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntityMapString,StringrequestEntitynewHttpEntity(params,headers);// 4. 发送请求自动使用双向认证ResponseEntityStringresponsemutualTlsRestTemplate.postForEntity(url,requestEntity,String.class);returnresponse.getBody();}}第五步服务器端验签美团侧逻辑示意虽然这是美团侧的逻辑但理解它有助于我们正确签名。// 伪代码美团服务器如何验签publicbooleanverifyRequest(MapString,Stringparams,StringclientPublicKeyPem){StringreceivedSignparams.remove(sign);// 1. 参数排序并拼接StringdataToVerifysortAndJoin(params);// 2. 使用你的公钥验签SignaturesignatureSignature.getInstance(SHA256withRSA);signature.initVerify(loadPublicKey(clientPublicKeyPem));signature.update(dataToVerify.getBytes(StandardCharsets.UTF_8));returnsignature.verify(Base64.getDecoder().decode(receivedSign));}通过以上“证书双向认证请求签名”的组合拳俱美开放平台确保了与美团霸王餐API交互的绝对安全作为外卖霸王餐API唯一供给源头我们为用户和合作伙伴提供了金融级的数据安全保障。本文著作权归 俱美开放平台 转载请注明出处
RELATED

相关推荐

C++语言算法教程——递归

C++语言算法教程——递归

引子 我们经常遇到 “递归” 这个名词,却不知道是什么意思,今天我们就讲一下递归 什么是递归 看这是递龟: 好了,我们讲完了 Y(^o^)Y 哈哈😄开个玩笑,我么我们来讲一个故事,听懂了&#xff…

📅 2026/10/9 10:38:23
生命游戏C++代码initgraph窗口版(有功能未开放)

生命游戏C++代码initgraph窗口版(有功能未开放)

由于作者实力较弱&#xff0c;代码可能产生漏洞&#xff0c;请原谅&#xff01;&#xff01; #include <bits/stdc.h> #include <graphics.h> #include <conio.h> #include <thread> #include <mutex> #include <chrono> #include <cst…

📅 2026/11/4 18:09:21
verilog HDLBits刷题[多路复用器]“Mux256to1v”---256-to-1 4-bit multiplexer

verilog HDLBits刷题[多路复用器]“Mux256to1v”---256-to-1 4-bit multiplexer

一、题目Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel0 should select bits in[3:0], sel1 selects bits in[7:4], sel2 selects bits in[11:8], etc.Expected solution length: Around 1–5 li…

📅 2026/9/14 21:04:38
MORE NEWS

更多资讯

📰

CAD注册表清理工具:解决AutoCAD安装残留问题

1. 工具定位与核心痛点解析这个CAD注册表清理工具本质上是一个针对AutoCAD系列软件卸载残留问题的专项解决方案。在十多年的CAD使用和教学经历中&#xff0c;我见过太多因为注册表残留导致的安装失败案例——明明已经卸载了旧版本&#xff0c;安装新版本时却提示"已安装&q…

📰

PostgreSQL从0到1选型与落地:能力边界、配置与故障排查

接手一个内部数据平台重构时&#xff0c;团队在选型上卡了整整两天。需求单摊开来什么都有&#xff1a;订单是标准的关系型结构&#xff0c;用户画像是一大坨嵌套 JSON&#xff0c;运营要按关键词搜工单正文&#xff0c;风控要算“三公里内”的门店&#xff0c;后来还追加了一个…

📰

通用大模型 vs 垂直行业大模型:选型要点与落地实践

这两年做大模型落地的朋友应该都有同一种感受&#xff1a;通用大模型像一把万能瑞士军刀&#xff0c;什么都行&#xff0c;什么都差口气&#xff1b;垂直行业大模型像一把定制手术刀&#xff0c;切得准&#xff0c;但打不打磨、打磨得好不好&#xff0c;直接决定你是救人还是误…

📰

数据结构核心原理与实战应用全解析

1. 数据结构基础概念全景解析在程序设计的江湖里&#xff0c;数据结构就像武侠世界中的内功心法。记得我第一次参加技术面试时&#xff0c;面试官在白板上画了个二叉树就让我现场实现遍历&#xff0c;那一刻突然意识到&#xff1a;不理解数据结构就像练武不扎马步&#xff0c;再…

📰

Oracle EBS财务模块三层结构、账套配置与总账数据流解析

简介&#xff1a;围绕 Oracle EBS 财务模块整理的五部分学习文档&#xff0c;面向正在接触 Oracle ERP 财务实施、运维或希望系统理解财务模块的初、中级读者&#xff0c;也适合作为培训参考&#xff0c;可用于梳理传统财务流程与 EBS 财务功能的对应关系。压缩包内共 1 个 doc…

📰

MSMQ与Spring Boot缓存预热提升电商系统性能

1. 项目概述&#xff1a;消息队列与缓存预热的工程实践在分布式系统架构中&#xff0c;消息队列和缓存机制是解决性能瓶颈的经典组合拳。最近我在一个电商促销系统项目中&#xff0c;就遇到了高并发下单导致的数据库压力问题。通过采用MSMQ实现异步消息处理&#xff0c;并结合S…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬