0


Springboot实战:基于HmacSHA256算法实现API签名验证

🧑 博主简介:历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“**历代文学**”)总架构师,

15年

工作经验,精通

Java编程

高并发设计

Springboot和微服务

,熟悉

Linux

ESXI虚拟化

以及

云原生Docker和K8s

,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。

在这里插入图片描述

在这里插入图片描述

Spring Boot 基于HmacSHA256算法实现API签名验证

在现代Web应用中,API的安全性至关重要。接口签名验证是一种常见的安全机制,用于确保请求的完整性和真实性。本文将详细介绍如何在

Spring Boot

应用中实现接口签名验证,并提供真实典型的代码示例。我们将使用

HmacSHA256

算法进行签名生成和验证。

HmacSHA256 算法简介

HmacSHA256 算法是一种消息认证码算法,它是 SHA-256 算法的变形版。通过使用密钥和散列函数,确保消息的认证性和完整性,防止消息被篡改。它广泛应用于网络安全领域,如 HTTPS 等协议。

HmacSHA256 算法具有安全性高实用性强易于实现灵活性高抗碰撞能力强等优点。在进行 HmacSHA256 算法运算时,需要传递密钥和数据两个参数,通过特定的方法将密钥转换成一个值,再与数据进行异或运算,并使用

SHA-256

哈希函数进行处理,得到一个 256 位的哈希值作为结果。

HmacSHA256 算法优点:

  1. 安全性高:通过使用密钥和散列函数,确保消息的认证性和完整性,防止消息被篡改。
  2. 实用性强:广泛应用于网络安全领域,如 HTTPS 等协议。
  3. 易于实现:实现过程相对简单,只需使用对应的加密库。
  4. 灵活性高:可将不同的散列函数和密钥组合使用,提高安全性。
  5. 抗碰撞能力强:具有较大的哈希值长度,减小了碰撞的概率。

一、接口签名验证原理

接口签名验证的核心思想是通过对请求参数进行加密生成签名,并将签名附加到请求中。服务器端接收到请求后,使用相同的算法对请求参数进行加密,并与请求中的签名进行比对。如果一致,则认为请求是合法的;否则,请求将被拒绝。

1.1 签名生成步骤

  1. 排序参数:将请求参数按字典序排序。
  2. 拼接参数:将排序后的参数按特定格式拼接成字符串。
  3. 加密签名:使用HmacSHA256算法对拼接后的字符串进行加密生成签名。
  4. 附加签名:将生成的签名附加到请求中。

1.2 签名验证步骤

  1. 获取请求参数:从请求中提取所有参数。
  2. 排序参数:将请求参数按字典序排序。
  3. 拼接参数:将排序后的参数按特定格式拼接成字符串。
  4. 加密签名:使用HmacSHA256算法对拼接后的字符串进行加密生成签名。
  5. 比对签名:将生成的签名与请求中的签名进行比对。

二、Spring Boot 实现接口签名验证

在Spring Boot中,我们可以通过自定义过滤器或拦截器来实现接口签名验证。以下是一个典型的实现示例。

2.1 创建签名工具类

首先,我们需要创建一个工具类来生成和验证签名。

importjavax.crypto.Mac;importjavax.crypto.spec.SecretKeySpec;importjava.nio.charset.StandardCharsets;importjava.util.Arrays;importjava.util.Base64;importjava.util.Map;publicclassSignUtil{privatestaticfinalStringSECRET_KEY="your_secret_key";// 密钥privatestaticfinalStringHMAC_SHA256="HmacSHA256";/**
     * 生成签名
     * @param params 请求参数
     * @return 签名
     */publicstaticStringgenerateSign(Map<String,String> params){// 按字典序排序String[] sortedKeys = params.keySet().toArray(newString[0]);Arrays.sort(sortedKeys);// 拼接参数StringBuilder paramStr =newStringBuilder();for(String key : sortedKeys){
            paramStr.append(key).append(params.get(key));}// 拼接密钥
        paramStr.append(SECRET_KEY);// 生成签名returnBase64.getEncoder().encodeToString(hmacSha256(paramStr.toString().getBytes(StandardCharsets.UTF_8),SECRET_KEY.getBytes(StandardCharsets.UTF_8)));}/**
     * 验证签名
     * @param params 请求参数
     * @param sign 请求中的签名
     * @return 签名是否有效
     */publicstaticbooleanverifySign(Map<String,String> params,String sign){if(sign ==null|| sign.isEmpty()){returnfalse;}String generatedSign =generateSign(params);return generatedSign.equals(sign);}/**
     * 使用HmacSHA256算法生成签名
     * @param data 数据
     * @param key 密钥
     * @return 签名
     */privatestaticbyte[]hmacSha256(byte[] data,byte[] key){try{Mac mac =Mac.getInstance(HMAC_SHA256);
            mac.init(newSecretKeySpec(key,HMAC_SHA256));return mac.doFinal(data);}catch(Exception e){thrownewRuntimeException("Failed to generate HMAC SHA256", e);}}}

2.2 创建拦截器

接下来,我们创建一个拦截器来拦截请求并进行签名验证。

importorg.springframework.stereotype.Component;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.util.Enumeration;importjava.util.HashMap;importjava.util.Map;@ComponentpublicclassSignInterceptorimplementsHandlerInterceptor{@OverridepublicbooleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)throwsException{// 获取请求参数Map<String,String> params =newHashMap<>();Enumeration<String> paramNames = request.getParameterNames();while(paramNames.hasMoreElements()){String paramName = paramNames.nextElement();
            params.put(paramName, request.getParameter(paramName));}// 获取请求中的签名String sign = request.getParameter("sign");// 验证签名if(!SignUtil.verifySign(params, sign)){
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            response.getWriter().write("Invalid signature");returnfalse;}returntrue;}}

2.3 配置拦截器

最后,我们需要在Spring Boot中配置拦截器。

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{@AutowiredprivateSignInterceptor signInterceptor;@OverridepublicvoidaddInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(signInterceptor).addPathPatterns("/**");// 拦截所有路径}}

三、Maven 依赖

为了确保以上代码示例能够正常运行,我们需要在

pom.xml

中添加以下依赖:

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Apache Commons Codec --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version></dependency></dependencies>

四、测试代码示例

为验证api签名功能正常,特意编写了一个简单的测试控制器和测试代码。

4.1 测试控制器

importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.Map;@RestControllerpublicclassTestController{@GetMapping("/test")publicStringtest(@RequestParamMap<String,String> params){return"Request is valid";}@GetMapping("/generateSign")publicStringgenerateSign(@RequestParamMap<String,String> params){returnSignUtil.generateSign(params);}}

4.2 测试代码

我们可以使用Postman或其他HTTP客户端工具来测试接口。

  1. 生成签名:- 请求URL:http://localhost:8080/generateSign- 请求参数:param1=value1&param2=value2- 获取生成的签名。
  2. 验证签名:- 请求URL:http://localhost:8080/test- 请求参数:param1=value1&param2=value2&sign=生成的签名- 验证返回结果是否为Request is valid

五、总结

通过以上步骤,我们成功在Spring Boot应用中实现了接口签名验证。这种机制可以有效防止请求被篡改和伪造,提高API的安全性。希望本文的示例代码和解释能够帮助你更好地理解和应用接口签名验证。

标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/lilinhai548/article/details/142174302
版权归原作者 码踏云端 所有, 如有侵权,请联系我们删除。

“Springboot实战:基于HmacSHA256算法实现API签名验证”的评论:

还没有评论