当前位置: 首页 > article >正文

API接口签名验证实战

API接口签名验证实战一、接口签名概述API签名验证是保护接口安全的重要手段防止请求被篡改或伪造。1.1 签名机制原理┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客户端 │ │ 网络 │ │ 服务端 │ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │ 1. 构造请求参数 │────▶│ 传输请求 │────▶│ 1. 获取请求参数 │ │ 2. 生成签名 │ │ │ │ 2. 重新生成签名 │ │ 3. 发送请求 │ │ │ │ 3. 验证签名 │ └─────────────────┘ └─────────────────┘ │ 4. 处理请求 │ └─────────────────┘1.2 签名要素要素说明示例AppKey应用标识app001AppSecret应用密钥xxxxxxTimestamp时间戳1704067200Nonce随机数abc123Signature签名结果md5(xxx)二、签名算法实现2.1 签名生成流程public class SignatureUtil { private static final String SIGN_METHOD MD5; private static final String CHARSET UTF-8; public static String generateSignature(MapString, String params, String appSecret) { // 1. 去除sign参数 params.remove(sign); // 2. 按字典序排序 ListString keys new ArrayList(params.keySet()); Collections.sort(keys); // 3. 拼接参数 StringBuilder sb new StringBuilder(); for (String key : keys) { String value params.get(key); if (value ! null !value.isEmpty()) { sb.append(key).append().append(value).append(); } } // 4. 拼接密钥 sb.append(key).append(appSecret); // 5. 计算签名 return md5(sb.toString()); } private static String md5(String input) { try { MessageDigest md MessageDigest.getInstance(SIGN_METHOD); byte[] digest md.digest(input.getBytes(CHARSET)); StringBuilder sb new StringBuilder(); for (byte b : digest) { sb.append(String.format(%02x, b)); } return sb.toString().toUpperCase(); } catch (Exception e) { throw new RuntimeException(MD5 calculation failed, e); } } }2.2 HMAC-SHA256签名public class HmacSignatureUtil { private static final String ALGORITHM HmacSHA256; public static String generateHmacSignature(MapString, String params, String appSecret) { params.remove(sign); ListString keys new ArrayList(params.keySet()); Collections.sort(keys); StringBuilder sb new StringBuilder(); for (String key : keys) { String value params.get(key); if (value ! null !value.isEmpty()) { sb.append(key).append().append(value).append(); } } sb.append(key).append(appSecret); try { Mac mac Mac.getInstance(ALGORITHM); SecretKeySpec keySpec new SecretKeySpec(appSecret.getBytes(), ALGORITHM); mac.init(keySpec); byte[] digest mac.doFinal(sb.toString().getBytes()); return Base64.getEncoder().encodeToString(digest); } catch (Exception e) { throw new RuntimeException(HMAC calculation failed, e); } } }三、签名验证实现3.1 验证过滤器public class SignatureFilter implements Filter { private static final long TIMESTAMP_TOLERANCE 5 * 60 * 1000; // 5分钟 Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { HttpServletRequest httpRequest (HttpServletRequest) request; HttpServletResponse httpResponse (HttpServletResponse) response; try { // 1. 获取参数 MapString, String params getRequestParams(httpRequest); // 2. 验证时间戳 String timestamp params.get(timestamp); validateTimestamp(timestamp); // 3. 验证随机数 String nonce params.get(nonce); validateNonce(nonce); // 4. 获取AppKey String appKey params.get(appKey); String appSecret getAppSecret(appKey); // 5. 验证签名 String sign params.get(sign); String expectedSign SignatureUtil.generateSignature(params, appSecret); if (!sign.equalsIgnoreCase(expectedSign)) { httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); httpResponse.getWriter().write(Invalid signature); return; } chain.doFilter(request, response); } catch (Exception e) { httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); } } private void validateTimestamp(String timestamp) { long ts Long.parseLong(timestamp); long now System.currentTimeMillis() / 1000; if (Math.abs(now - ts) TIMESTAMP_TOLERANCE / 1000) { throw new RuntimeException(Invalid timestamp); } } private void validateNonce(String nonce) { if (nonce null || nonce.length() 8) { throw new RuntimeException(Invalid nonce); } } }3.2 Nonce去重public class NonceManager { private final StringRedisTemplate redisTemplate; private static final String PREFIX nonce:; private static final long EXPIRE_SECONDS 5 * 60; // 5分钟 public void validateNonce(String nonce) { String key PREFIX nonce; Boolean exists redisTemplate.hasKey(key); if (Boolean.TRUE.equals(exists)) { throw new RuntimeException(Duplicate nonce); } redisTemplate.opsForValue().set(key, true, EXPIRE_SECONDS, TimeUnit.SECONDS); } }四、请求示例4.1 客户端请求public class ApiClient { private String appKey app001; private String appSecret secret123; public String sendRequest(String url, MapString, Object data) { MapString, String params new HashMap(); params.put(appKey, appKey); params.put(timestamp, String.valueOf(System.currentTimeMillis() / 1000)); params.put(nonce, UUID.randomUUID().toString().replace(-, ).substring(0, 16)); for (Map.EntryString, Object entry : data.entrySet()) { params.put(entry.getKey(), String.valueOf(entry.getValue())); } String sign SignatureUtil.generateSignature(params, appSecret); params.put(sign, sign); // 发送请求... return doPost(url, params); } }4.2 curl示例curl -X POST http://api.example.com/endpoint \ -H Content-Type: application/x-www-form-urlencoded \ -d appKeyapp001 \ -d timestamp1704067200 \ -d nonceabc123def456 \ -d datatest \ -d signA1B2C3D4E5F6五、安全加固5.1 使用HTTPSserver: ssl: enabled: true key-store: classpath:keystore.p12 key-store-password: password key-store-type: PKCS12 key-alias: tomcat5.2 IP白名单public class IpWhitelistFilter implements Filter { private SetString whitelist Set.of( 192.168.1.1, 10.0.0.0/8 ); Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { String clientIp getClientIp((HttpServletRequest) request); if (!isIpWhitelisted(clientIp)) { ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_FORBIDDEN); return; } chain.doFilter(request, response); } }5.3 频率限制public class RateLimitFilter implements Filter { private final StringRedisTemplate redisTemplate; private static final int MAX_REQUESTS 100; private static final int TIME_WINDOW_SECONDS 60; Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { String clientIp getClientIp((HttpServletRequest) request); String key rate_limit: clientIp; Long count redisTemplate.opsForValue().increment(key); if (count 1) { redisTemplate.expire(key, TIME_WINDOW_SECONDS, TimeUnit.SECONDS); } if (count MAX_REQUESTS) { ((HttpServletResponse) response).setStatus(429); return; } chain.doFilter(request, response); } }六、签名算法对比算法安全性性能适用场景MD5低高内部系统SHA-1中高一般场景SHA-256高中重要场景HMAC-SHA256高中对外API七、最佳实践7.1 签名规范参数排序按字典序升序排列空值处理忽略空参数编码格式统一使用UTF-8签名格式统一大写或小写7.2 安全建议密钥管理使用密钥管理服务存储密钥定期轮换定期更换AppSecret日志审计记录签名验证失败日志异常监控监控异常签名请求7.3 常见问题问题原因解决方案签名不一致参数顺序不同统一排序规则时间戳过期客户端时间不准增加时间容错Nonce重复请求重放实现Nonce去重八、总结API签名验证是保护接口安全的重要手段选择合适算法根据安全需求选择HMAC-SHA256实现完整验证时间戳、Nonce、签名缺一不可配合其他措施HTTPS、IP白名单、频率限制做好密钥管理使用安全的密钥存储方案通过以上措施可以有效防止接口被篡改和重放攻击。

相关文章:

API接口签名验证实战

API接口签名验证实战 一、接口签名概述 API签名验证是保护接口安全的重要手段,防止请求被篡改或伪造。 1.1 签名机制原理 ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 客…...

API安全设计与防护实战

API安全设计与防护实战 一、API安全概述 API作为系统间交互的接口,是攻击的主要目标。一个安全的API设计需要考虑多个层面的防护,包括认证、授权、数据保护、攻击防护等。 二、API认证机制 2.1 API Key认证 Component public class ApiKeyFilter ex…...

AI知识管理不是工具升级,而是教学主权重构:一位特级教师用18个月完成“教案→知识流→认知干预”三级跃迁(全程数据脱敏实录)

更多请点击: https://intelliparadigm.com 第一章:AI知识管理在教育领域的应用 AI知识管理正深刻重塑教育生态,通过智能索引、语义理解与个性化推荐,将碎片化教学资源转化为可检索、可推理、可演化的结构化知识网络。教师可借助自…...

毕业论文神器!2026年必备AI论文软件榜单,免费版也能写合规初稿

2026 年实测 10 款主流 AI 论文工具,千笔AI以全流程覆盖 语义级降重 免费查重领跑综合榜;ThouPen 稳坐留学生毕业全流程工具头把交椅;免费工具中DeepSeek Scholar、豆包学术版表现亮眼,30 分钟即可生成万字高质量初稿&#xff0…...

显卡驱动彻底清理解决方案:Display Driver Uninstaller专业使用指南

显卡驱动彻底清理解决方案:Display Driver Uninstaller专业使用指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers…...

3分钟解决Mac与Windows文件交换难题:Nigate免费NTFS读写工具完全指南

3分钟解决Mac与Windows文件交换难题:Nigate免费NTFS读写工具完全指南 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and…...

Switch大气层系统终极指南:从新手到高手的完整成长路径

Switch大气层系统终极指南:从新手到高手的完整成长路径 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 想要彻底释放你的Switch游戏潜力吗?大气层系统(A…...

Go语言CI/CD流水线实践

Go语言CI/CD流水线实践 引言 CI/CD(持续集成/持续部署)是现代软件开发的核心实践。本文将深入探讨如何为Go语言项目构建高效的CI/CD流水线。 一、CI/CD概述 1.1 CI/CD流程 代码提交 -> 代码审查 -> 构建 -> 测试 -> 部署 -> 监控1.2 关键…...

3分钟搞定Windows桌面整理:NoFences免费开源工具终极指南

3分钟搞定Windows桌面整理:NoFences免费开源工具终极指南 【免费下载链接】NoFences 🚧 Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否每天都要在杂乱的Windows桌面上寻找文件&#xff…...

边缘计算部署:将计算能力延伸到网络边缘

边缘计算部署:将计算能力延伸到网络边缘 一、边缘计算部署概述 1.1 边缘计算部署的定义 边缘计算部署是指将计算资源和应用服务部署到靠近数据源或用户的网络边缘位置的过程。它通过在边缘位置处理数据,减少延迟,提高响应速度,并降…...

构建可持续的阅读书源生态:从基础导入到高级管理策略

构建可持续的阅读书源生态:从基础导入到高级管理策略 【免费下载链接】Yuedu 📚「阅读」自用书源分享 项目地址: https://gitcode.com/gh_mirrors/yu/Yuedu 在数字阅读日益普及的今天,阅读APP已成为广大书迷获取内容的重要渠道。然而&…...

分布式系统测试:验证分布式系统的正确性和性能

分布式系统测试:验证分布式系统的正确性和性能 一、分布式系统测试概述 1.1 分布式系统测试的定义 分布式系统测试是指对分布式系统进行验证和评估的过程,包括功能测试、性能测试、可靠性测试和安全性测试等方面。它确保分布式系统在各种场景下都能正确、…...

当Agent开始质疑你的原始数据——AI驱动的数据质量自治体系构建(含动态污点追踪与因果溯源模块)

更多请点击: https://intelliparadigm.com 第一章:当Agent开始质疑你的原始数据——AI驱动的数据质量自治体系构建(含动态污点追踪与因果溯源模块) 在传统数据治理范式中,数据质量校验往往滞后于数据摄入,…...

【Appium 系列】第18节-重试与容错 — 移动端测试的稳定性保障

配套代码:utils/retry.py、tests/test_login_api.py说明:本节所有代码示例均来自一个真实的移动端自动化测试项目,已做模糊化处理。为什么需要重试移动端测试比 Web 测试更容易出现偶发性失败。以下几种情况在本地和 CI 上反复出现&#xff1…...

小模型爆发出惊人能量!斯坦福开源框架AgentFlow如何实现复杂任务中的可靠工具使用?

本文介绍了斯坦福大学开源的模块化智能体框架AgentFlow,它通过独特的架构设计和训练方法,在工具集成和规划能力上取得了突破性进展。AgentFlow以Qwen-2.5-7B-Instruct为基础,在10个基准测试中表现突出,超越了大50倍的模型和GPT-4o…...

大模型底座的技术路线

主流大模型目前以token为单位处理文本,因其算力效率高、生态成熟。但byte-level/tokenizer-free路线正快速发展,它更端到端、跨语言统一且对噪声文本鲁棒。未来几年,外部接口可能仍用token,内部却将更多采用byte、patch或latent s…...

SenseNova-U1多模态模型深度解析:NEO-unify架构如何颠覆传统

SenseNova-U1多模态模型深度解析:NEO-unify架构如何颠覆传统 副标题: 从视觉编码器到端到端统一,附实战应用指南 一、痛点:为什么多模态模型这么复杂? 很多开发者第一次接触多模态模型时,会被各种架构绕晕:视觉编码器、文本解码器、适配器、投影层… 感觉像在看天书。 …...

大脑规则:为什么你学不进去?10个科学方法提升学习效率

大脑规则:为什么你学不进去?10个科学方法提升学习效率 副标题: 从进化论到认知科学,附实战学习方案 一、痛点:为什么你总是学不进去? 你有没有这样的经历: 坐在书桌前,书翻开了,但脑子一片空白 熬夜学习,第二天效率更低,形成恶性循环 一边看视频一边回消息,结果什…...

神经网络从入门到精通:10个核心概念+8个实战代码,小白也能懂

神经网络从入门到精通:10个核心概念+8个实战代码,小白也能懂 副标题: 从像素到概念的函数映射,附完整训练流程实战 一、痛点:为什么神经网络这么难理解? 很多初学者第一次接触神经网络时,会被各种术语绕晕:神经元、权重、偏置、激活函数、反向传播、梯度下降… 感觉像…...

LangGraph多智能体工作流:从线性执行到网状协作的重构

LangGraph多智能体工作流:从线性执行到网状协作的重构 1. 标题 (Title) 为了精准覆盖核心关键词、吸引不同层次的读者(AI应用开发者、LangChain进阶学习者、多智能体系统架构师),我准备了以下4个差异化标题: 《LangGraph 重塑AI协作:告别LangChain AgentExecutor的“单线…...

Harness的配置漂移检测与自动修复

云原生时代的稳定性利器:Harness配置漂移检测与自动修复全指南 引言 痛点引入 相信每一位DevOps工程师、SRE或者运维负责人都遇到过这样的噩梦: 测试环境验证了3天的功能,上线到生产10分钟就出现503错误,排查了2小时才发现&…...

Qwen模型 LeetCode 2585. 获得分数的方法数 TypeScript实现

哇!TypeScript版本来啦~这道题用TS写起来特别优雅,类型安全又清晰!让我给你展示一个高效又易读的实现!typescript function waysToReachTarget(target: number, types: number[][]): number {const MOD 1000000007;//…...

如何重塑贴吧体验:贴吧Lite带来的极致纯净浏览革新

如何重塑贴吧体验:贴吧Lite带来的极致纯净浏览革新 【免费下载链接】TiebaLite 贴吧 Lite 项目地址: https://gitcode.com/gh_mirrors/tieb/TiebaLite 厌倦了官方贴吧应用的臃肿体验和无处不在的广告干扰?贴吧Lite作为一款革命性的第三方贴吧客户…...

终极指南:如何免费快速上手Method Draw在线SVG编辑器

终极指南:如何免费快速上手Method Draw在线SVG编辑器 【免费下载链接】Method-Draw Method Draw, the SVG Editor for Method of Action 项目地址: https://gitcode.com/gh_mirrors/me/Method-Draw 如果你正在寻找一款简单高效的在线SVG编辑器,那…...

终极指南:无需微软账户离线启用Windows Insider预览计划的完整方案

终极指南:无需微软账户离线启用Windows Insider预览计划的完整方案 【免费下载链接】offlineinsiderenroll OfflineInsiderEnroll - A script to enable access to the Windows Insider Program on machines not signed in with Microsoft Account 项目地址: http…...

《离别的最后》的内容入口:收尾场景如何被记住

从内容传播角度看,《离别的最后》的入口在“最后”这个收束动作。它不是笼统告别,而是写到一段关系、一个阶段或一次转身即将落下尾音的时刻。这首歌不适合被写成普通伤感推荐。更准确的角度,是把它放在收尾场景里:删掉草稿、收起…...

SpringBoot+Vue旅游管理系统源码+论文

代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 分享万套开题报告任务书答辩PPT模板 作者完整代码目录供你选择: 《SpringBoot网站项目》1800套 《SSM网站项目》1500套 《小程序项目》1600套 《APP项目》1500套 《Python网站项目》…...

书匠策AI深度拆解:2025年毕业论文竟然能这样“无痛通关“?|论文科普必看

各位正在被毕业论文反复折磨的同学们,今天这篇文章,我要用最接地气的方式,给你们拆解一个让我直呼"早该有了"的工具——书匠策AI( 官网直达:www.shujiangce.com)。 先说句大实话:写毕…...

歌词滚动姬:重新定义你的歌词制作体验,让每一句歌词都完美同步

歌词滚动姬:重新定义你的歌词制作体验,让每一句歌词都完美同步 【免费下载链接】lrc-maker 歌词滚动姬|可能是你所能见到的最好用的歌词制作工具 项目地址: https://gitcode.com/gh_mirrors/lr/lrc-maker 还在为制作LRC歌词而烦恼吗&a…...

书匠策AI降重降AIGC实测:论文圈的“消音器“到底有多猛?官网www.shujiangce.com深度拆解

各位还在论文泥潭里挣扎的宝子们,今天这期内容可能会让你少熬三个通宵。 我最近收到最多的私信就是:"博主,我查重42%,AIGC检测28%,导师说再改不过就延毕,怎么办?"说实话,…...