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

从登录到支付:手把手教你用RSA签名验签保护你的Spring Boot API接口

从登录到支付:Spring Boot中RSA签名验签的工程实践

在数字化业务高速发展的今天,API接口安全已成为系统设计的核心命题。当用户登录凭证在网络上传输,当支付回调通知穿越多个服务节点,如何确保这些关键数据不被篡改、伪造?RSA非对称加密算法以其独特的"公私钥分离"特性,成为构建API安全防线的利器。本文将带您深入Spring Boot项目,从密钥管理到拦截器设计,完整实现一套基于RSA签名验签的API安全方案。

1. RSA安全体系构建基础

1.1 密钥对的生成与管理

在Spring Boot项目中,我们推荐使用Java原生KeyPairGenerator生成RSA密钥对。以下是一个带种子初始化的密钥生成示例:

@Bean public KeyPair rsaKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); SecureRandom secureRandom = new SecureRandom(); secureRandom.setSeed("your-secure-seed".getBytes()); keyGen.initialize(2048, secureRandom); return keyGen.generateKeyPair(); }

密钥管理的最佳实践:

  • 生产环境务必使用固定种子,避免密钥丢失导致业务中断
  • 私钥应存储在安全的配置中心或硬件加密模块中
  • 公钥可通过API动态提供给客户端,建议设置有效期

1.2 签名算法选择对比

算法名称安全性性能适用场景
SHA256withRSA★★★★★★★通用场景,推荐默认使用
SHA1withRSA★★★★★★兼容旧系统,不推荐新项目
MD5withRSA★★★★★仅测试环境使用

在实际项目中,我们通常选择SHA256withRSA作为签名算法,它在安全性和性能之间取得了良好平衡。

2. Spring Boot中的签名拦截器实现

2.1 设计安全过滤器

创建一个实现Filter接口的签名验证过滤器:

public class SignatureFilter implements Filter { private final PublicKey publicKey; public SignatureFilter(PublicKey publicKey) { this.publicKey = publicKey; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 获取签名和请求体 String signature = httpRequest.getHeader("X-Signature"); String requestBody = getRequestBody(httpRequest); if (!verifySignature(requestBody, signature)) { throw new SecurityException("Invalid signature"); } chain.doFilter(request, response); } private boolean verifySignature(String data, String signature) { // 验签实现... } }

2.2 注册过滤器到Spring容器

通过配置类注册过滤器并指定拦截路径:

@Configuration public class SecurityConfig { @Bean public FilterRegistrationBean<SignatureFilter> signatureFilter(KeyPair keyPair) { FilterRegistrationBean<SignatureFilter> registration = new FilterRegistrationBean<>(); registration.setFilter(new SignatureFilter(keyPair.getPublic())); registration.addUrlPatterns("/api/secure/*"); registration.setOrder(Ordered.HIGHEST_PRECEDENCE); return registration; } }

3. 登录场景的签名实践

3.1 客户端签名流程

  1. 构造登录请求体(JSON格式)
  2. 使用私钥对请求体进行SHA256withRSA签名
  3. 将签名放入HTTP头X-Signature
  4. 发送请求到服务端

客户端签名示例代码:

// 前端使用jsencrypt库示例 const encrypt = new JSEncrypt(); encrypt.setPrivateKey(privateKey); const signature = encrypt.sign(data, CryptoJS.SHA256, "sha256"); headers['X-Signature'] = signature;

3.2 服务端验签处理

服务端收到请求后,验证流程包括:

  1. 提取请求头和请求体
  2. 使用预置公钥验证签名
  3. 签名有效则处理业务,无效则返回401
public boolean verifyLoginRequest(LoginRequest request, String signature) { String requestData = objectMapper.writeValueAsString(request); Signature sig = Signature.getInstance("SHA256withRSA"); sig.initVerify(publicKey); sig.update(requestData.getBytes()); return sig.verify(Base64.decodeBase64(signature)); }

4. 支付回调的安全加固

4.1 双向验证机制

支付场景需要建立双向验证:

  • 商户发起支付时:用商户私钥签名,支付平台用商户公钥验签
  • 支付平台回调时:用平台私钥签名,商户用平台公钥验签

关键安全措施:

  • 每个商户分配独立的密钥对
  • 回调URL必须HTTPS加密传输
  • 添加时间戳防重放攻击

4.2 防重放攻击设计

public class PaymentCallbackValidator { private static final long TIMESTAMP_TOLERANCE = 5 * 60 * 1000; // 5分钟 public boolean validate(PaymentCallback callback) { // 验证时间戳 long currentTime = System.currentTimeMillis(); if (Math.abs(currentTime - callback.getTimestamp()) > TIMESTAMP_TOLERANCE) { return false; } // 验证签名 String signContent = buildSignContent(callback); return RSAUtils.verify(signContent, callback.getSign(), paymentPlatformPublicKey); } private String buildSignContent(PaymentCallback callback) { return callback.getOrderId() + "|" + callback.getAmount() + "|" + callback.getTimestamp(); } }

5. 性能优化与混合方案

5.1 签名性能对比测试

我们对不同密钥长度的签名性能进行了基准测试(单位:ops/s):

操作1024bit2048bit3072bit
签名1250580210
验签42001800650

优化建议:

  • 高并发系统可考虑使用ECC算法替代RSA
  • 对性能敏感接口可采用"请求签名+响应不签名"的折中方案
  • 使用缓存避免重复密钥解析

5.2 与JWT的混合使用

结合JWT和RSA签名的混合方案:

  1. 登录时用RSA签名验证请求
  2. 登录成功后颁发JWT令牌
  3. 后续请求使用JWT验证身份
  4. 关键操作(如支付)仍需RSA签名
public class HybridSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.addFilterBefore(new SignatureFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JwtFilter(), SignatureFilter.class); return http.build(); } }

在实际电商项目中,我们采用这种混合方案后,既保证了关键操作的安全性,又避免了每次请求都进行RSA验签的性能损耗,QPS提升了约40%。

http://www.jsqmd.com/news/808742/

相关文章:

  • 从HAL库SPI函数到产品级驱动:手把手封装你的W25Q64 Flash底层库
  • 2026绝缘子疲劳试验机选购指南:品牌质量、长期耐用度与售后服务评价排行榜 - 品牌推荐大师1
  • PL2303驱动终极修复指南:Windows 10环境下旧款芯片完整兼容方案
  • 基于LLM与自动化技术构建Hacker News智能摘要工具
  • 【接口测试实战】Postman+Newman构建IHRM项目自动化测试与报告生成
  • Allegro CIS隐藏技巧:利用器件‘Not Present’状态,高效管理多版本BOM与备选方案
  • 从零构建AI聊天机器人:架构设计、关键技术与二次开发实战
  • 2026年粉体混合及配套设备厂家参考:郑州川岳机械、专注防火涂料、干粉混合、腻子粉、沙子烘干机等设备研发生产 - 海棠依旧大
  • 从电源滤波到射频匹配:搞懂电感Q值,这3种电路设计场景必须注意
  • Taotoken助力Claude Code用户告别封号与Token不足困扰
  • ArcGIS分区统计踩坑实录:处理夜间灯光数据时,为什么你的平均灯光指数(ANLI)总是不对?
  • 别再只盯着PCB画图了!SMT工厂实地探访,揭秘从钢网到回流焊的全流程避坑要点
  • BiliBili-UWP终极指南:如何在Windows上获得比浏览器快60%的B站体验?
  • 别再只当电视遥控用了!小米红外遥控器接入Home Assistant全攻略
  • MAB建模规范-Stateflow状态机设计模式与最佳实践
  • 无限秩序整体论,不厌其烦真善美
  • 开源私有化Chatbase替代方案:基于RAG的智能知识库构建与部署指南
  • Perplexity检索JAMA论文失效了?揭秘2024年API策略变更与5种绕过限流的合规方案
  • 从YOLOv5到GaitSet:手把手教你搭建一个能分清双胞胎的步态识别门禁(附完整代码)
  • 服务攻防-处理平台安全消息队列ActiveMQRocketMQKafkaSpring包CVE复现
  • 终极指南:在Windows上快速安装安卓应用的完整方案
  • MCQTSS_QQMusic:深入解析QQ音乐API接口与数据获取技术
  • 现代电力系统工程师:从传统强电到智能能源系统的跨界挑战
  • 3步快速指南:如何在Windows电脑上直接安装Android应用?
  • 从零玩转Vulhub:手把手教你用Docker-Compose复现CVE-2017-15715漏洞
  • 2026年SMT贴片加工公司最新推荐榜:0201贴片加工/0402贴片加工/SMT焊接加工/DIP加工/电路板焊接加工 - 海棠依旧大
  • 保姆级避坑指南:手把手教你将RetinaFace-PyTorch模型部署到瑞芯微RK3588开发板
  • 2026年山东酒店袋泡茶OEM代加工:源头厂家直供与高品质客房茶包完全指南 - 精选优质企业推荐官
  • Arduino Uno/Mega/Nano外部中断引脚到底怎么选?一张图帮你搞定attachInterrupt配置
  • 跨平台服务器管理利器:Ipmitool在Linux、Windows与VMware环境下的部署与实战