springboot使用SHA256加密算法对接口访问控制

SpringBoot安全实践:HMAC-SHA256签名在API防护中的高效应用 本文详细介绍了SpringBoot中HMAC-SHA256签名机制在API防护中的高效应用,包括核心原理、拦截器实现方案及高并发场景下的优化策略。通过密钥动态管理和签名缓存机制,显著提升API安全性和性能,适用于电商、金融等高安全需求场景。 阅读详情

使用场景

由于业务系统较多,且存在很多个提供给第三方系统的查询接口,第三方系统属于外部系统,个别系统在调用内部系统接口时可能存在安全风险,在周五项目组评审后决定,在对外提供的接口中,请求方需要添加私钥请求校验,我方使用 SHA256 算法计算签名,然后进行Base64 encode,最后再进行urlEncode,来得到最终的签名。周末闲来无事,简单研究一波(基于内网中其他系统已有的类似功能,结合外网资料)。

学习使用

创建一个简单的springboot项目,目录结构如下:
在这里插入图片描述
由于并不是对所有接口进行过滤验证,所以决定添加自定义注解用来判定是否需要鉴权:

@Documented
@Inherited
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
    boolean validate() default true;//是否需要鉴权
}

需要创建一个controller,假设是对外提供的接口服务:

@Controller
public class TestController {

    @Auth
    @GetMapping("/auth" )
    private String myTest(){
        System.out.println("mystest.....");
        return "ok";
    }
}

因为需要对接口进行过滤拦截,所以需要创建拦截器,通过继承HandlerInterceptorAdapter(待深入学习)实现的过滤拦截:

public class AuthSercurityInterceptor extends HandlerInterceptorAdapter {
    @Value("${auth.secret.info:12345}")
    private String secret;
    @Value("${auth.need:true}")
    private Boolean needAuth;

    //HEADER Authorization
    private static final String INFO_TIME = "timestamp";
    private static final String INFO_SIGN = "sign";
    private static final String AUTH_HEADER = "Authorization";

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public Boolean getNeedAuth() {
        return needAuth;
    }

    public void setNeedAuth(Boolean needAuth) {
        this.needAuth = needAuth;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (needAuth==null||!needAuth){
            return true;
        }
        if(!handler.getClass().isAssignableFrom(HandlerMethod.class)){
            return true;
        }
        Auth auth = ((HandlerMethod)handler).getMethodAnnotation(Auth.class);
        if (auth==null||!auth.validate()){
            return true;
        }
        String authorization = request.getHeader(AUTH_HEADER);
        System.out.println("authorization is :" + authorization);
        String[] info = authorization.trim().split(",");
        if (info==null||info.length<1){
            throw new Exception("error .....");
        }
        String timestamp = null;
        String sign = null;
        for (int i = 0; i < info.length; i++) {
            String str = info[i].trim();
            if (StringUtils.isEmpty(str)){
                continue;
            }
            String[] strSplit = str.split("=");
            if (strSplit==null||strSplit.length!=2){
                continue;
            }
            String key = strSplit[0];

            String value = strSplit[1];

            if (INFO_TIME.equalsIgnoreCase(key)){
                timestamp = value;
                System.out.println("timestamp is :" + timestamp);
            }
            if (INFO_SIGN.equalsIgnoreCase(key)){
                sign = value;
                System.out.println("sign is :" + sign);
            }
        }
        if (StringUtils.isEmpty(timestamp)||StringUtils.isEmpty(sign)){
            throw new Exception("error timestamp or sign is null");
        }
        String sha256Str = SHAUtils.getSHA256Str(secret,timestamp);
        System.out.println("sha256str is :" + sha256Str);
            if (StringUtils.isEmpty(sha256Str)){
                throw new Exception("sha256Str is null ...");
            }
            if (!sha256Str.equals(sign)){
                throw new Exception("sign error...");
            }
            return super.preHandle(request,response,handler);
        }

}

因为新增了自定义拦截器,所以需要将自定义拦截器进行配置:
AuthConfig.java

@Configuration
public class AuthConfig extends WebMvcConfigurationSupport {
    @Bean    //自定义的AuthSercurityInterceptor 
    public AuthSercurityInterceptor authSercurityInterceptor(){
        return new AuthSercurityInterceptor();
    }

    @Override    //进行注册添加AuthSercurityInterceptor 
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authSercurityInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

SHA256 算法计算签名,然后进行Base64 encode,最后再进行urlEncode,来得到最终的签名:

public class SHAUtils {
    public static final String ENCODE_TYPE_HMAC_SHA_256 ="HmacSHA256";
    public static final String ENCODE_UTF_8_LOWER ="utf-8";
    public static final String ENCODE_UTF_8_UPPER ="UTF-8";

    public static String getSHA256Str(String secret,String message) throws Exception {
        if (StringUtils.isEmpty(secret)){
            return null;
        }
        String encodeStr;
        try{
            //HMAC_SHA256 加密
            Mac HMAC_SHA256 = Mac.getInstance(ENCODE_TYPE_HMAC_SHA_256);
            SecretKeySpec secre_spec = new SecretKeySpec(secret.getBytes(ENCODE_UTF_8_UPPER),ENCODE_TYPE_HMAC_SHA_256);
            HMAC_SHA256.init(secre_spec);
            byte[] bytes = HMAC_SHA256.doFinal(message.getBytes(ENCODE_UTF_8_UPPER));
            if (bytes==null&&bytes.length<1){
                return null;
            }

            //字节转换为16进制字符串
            String SHA256 =byteToHex(bytes);
            if (StringUtils.isEmpty(SHA256)){
                return null;
            }
            //base64
            String BASE64 = Base64.getEncoder().encodeToString(SHA256.getBytes(ENCODE_UTF_8_UPPER));
            if (StringUtils.isEmpty(BASE64)){
                return null;
            }

            //url encode
            encodeStr = URLEncoder.encode(BASE64,ENCODE_UTF_8_LOWER);
        }catch (Exception e){
            throw new Exception("get 256 info error ....");
        }
        return encodeStr;
    }

    private static String byteToHex(byte[] bytes){

        if (bytes==null){
            return null;
        }
        StringBuffer stringBuffer = new StringBuffer();
        String temp=null;
        for (int i = 0; i <bytes.length ; i++) {
            temp = Integer.toHexString(bytes[i]&0xff);
            if (temp.length()==1){
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }
}

运行程序,在auth.need:true设置为false的时候,接口正常访问和返回,
在这里插入图片描述
改为true后,就请求接口的时候就要传递Authorization在请求头中,要包含timestamp和sign,否则会报空指针异常,假如对接系统方目前还不知道具体怎样传参数才能请求到接口,随意在请求头的Authorization加上例如timestamp=1590829472,sign=/auth后去请求,因为秘钥不对,所以无法请求到接口。

authorization is :timestamp=1590829472,sign=/auth
timestamp is :1590829472
sign is :/auth
2020-05-30 17:56:05.632 ERROR 13616 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.Exception: sign error...] with root cause

java.lang.Exception: sign error...

将最终的sha256str作为签名信息交给经过授权的对接第三方,让他们在请求头Authorization,将新提供的信息添加上timestamp=1590829472,sign=ZGQwNTY0MDNiYzM3OWI5ZmEyMGY2ZDU0ZTk0NzBhMzc5ODgyZDY4OWM2YWJmNzYyNzM2YmZlMzY0ZjMyYmE2Mw%3D%3D,即可成功请求到接口信息。
在这里插入图片描述

文件上传与下载(sha256加密) 技术:springboot、mybatisplus 目标: java 运行环境:jdk11 数据库:sqlite3(版本不限) 任务:使用一个springboot作为基础做一个文件上传下载 要求: 1:上传的文件先进行sha256加密,将摘要值保存至数据库; 2.将文件进行压缩、保存至项目当前路径下的uplaodfile目录下 3.下载 方法一的实现: 步骤: 1:添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h 阅读详情

相关推荐

SpringBoot集成EMQX:基于JWT的客户端认证实战指南

本文详细介绍了如何在SpringBoot项目中集成EMQX,并基于JWT实现客户端认证。通过环境准备、EMQX配置、JWT令牌生成、MQTT客户端连接等实战步骤,帮助开发者快速掌握安全可靠的物联网通信方案。文章特别强调了JWT认证的最佳实践和常见问题解决方案,适用于Java开发者构建安全的MQTT应用。

weixin_28688385的博客 363

Spring Boot学习篇(十)

本文讲述的是在spring boot项目环境下,shiro框架的登录实例(数据库是以密文存储,不含记住密码)

SSS4362的博客 1404

SpringBoot整合AES实现文件加解密:从原理到工程实践

在数据安全领域,加密技术是保护敏感信息的核心手段。对称加密算法因其高效性,在文件加密场景中被广泛应用,其中AES(高级加密标准)因其安全性和速度成为国际通用标准。其工作原理基于分组密码,通过密钥对数据进行混淆和扩散,确保未经授权者无法解读原始内容。这项技术的工程价值在于,它能在应用层透明地实现文件内容的保护,无需依赖特定存储服务。在实际开发中,结合SpringBoot框架,可以构建出灵活、可复用的文件加解密服务组件,适用于后台管理系统、文档安全存储等多种需要保护敏感文件的应用场景。本文通过整合AES算法,详

weixin_34345753的博客 479

Spring Boot 知识点总结

完成激活:如果你输入的激活码有效且正确,IntelliJ IDEA将完成激活过程。安装IntelliJ IDEA:下载完成后,运行安装包,按照提示完成安装过程。启动IntelliJ IDEA:安装完成后,通过桌面上的快捷方式或启动菜单中的图标,打开IntelliJ IDEA。输入激活码:当你获得了激活码后,在激活界面中输入激活码,然后点击 “Activate” 进行激活。在“环境变量”窗口中,找到“系统变量”部分,点击“新建”按钮。在“环境变量”窗口中,找到“系统变量”部分,点击“新建”按钮。

weixin_73163907的博客 149

SpringBoot实现加密数据模糊查询:HMAC分片索引架构与实战

在数据安全领域,加密存储是保护敏感信息的基石,常用AES等强加密算法确保数据机密性。其原理是通过密钥对明文进行转换,生成无法直接解读的密文。然而,传统加密技术面临一个核心挑战:如何在数据加密后仍支持高效的模糊查询,这对于用户检索、风控等场景至关重要。可搜索加密技术应运而生,它旨在解决密文上的检索问题,其中一种工程实践思路是采用“索引化”策略,在安全与性能间取得平衡。HMAC(基于哈希的消息认证码)技术因其不可逆性和密钥依赖性,常被用于构建安全索引,通过对数据分片计算HMAC值,既能支持模糊匹配,又不泄露明文

weixin_33826609的博客 534

SpringBoot整合SpringSecurity与SSH:构建企业级安全应用骨架实战

在构建现代企业级应用时,权限控制与安全传输是保障系统安全的两大基石。权限控制基于RBAC(基于角色的访问控制)模型,通过用户、角色、权限的关联,实现从菜单到按钮的精细化访问管理,其核心原理在于前后端协同校验,前端负责体验优化,后端通过注解拦截器进行强制校验,构筑了完整的防护体系。安全传输则利用SSH协议,通过公钥认证和加密隧道,为管理接口或服务间通信提供点对点的安全保障,有效提升了内网应用的安全水位。这两项技术的结合,为后台管理系统、运营平台等高敏感度应用场景提供了从身份认证、访问控制到数据传输的全链路安全

weixin_30607029的博客 482

【SpringBoot框架篇】15.使用shiro对web应用进行权限认证

使用shiro对web应用进行权限认证

皓亮君的博客 3060

TLS 到 mTLS: 从网络传输安全到零信任架构

真实工程届场景,不做八股小丑 >我们都知道https用了tls/ssl加密通信,那现在mtls慢慢普及或是场景应用,今天就来讲讲 --- 1. 从单向认证到双向认证 ``` TLS (单向认证) - 客户端验证服务器 - 类似:你验证银行身份 mTLS (双向认证) - 客户端和服务器互相验证 - 类似:银行也要验证你的身份 ```

jsjbrdzhh的博客 3770

SpringBoot 整合 Spring Security 、JWT 实现认证、权限控制

Spring Security 和 JWT 实现认证、权限控制是一种在Web应用中保障安全的重要手段。Spring Security是一个功能强大的身份验证和访问控制框架,它提供了完善的认证机制和方法级的授权功能。JWT(JSON Web Token)则是一种基于Token的认证方案,用于在通信双方之间传递安全信息。将Spring Security与JWT整合,可以实现有效的认证和权限管理,提升系统的安全性。Spring Security的核心是一系列过滤器链,不同的功能经由不同的过滤器实现。例如,

2301_76419561的博客 1592

EMQX内置用户认证实战:Spring Boot集成MQTT的完整配置指南

本文详细介绍了如何在Spring Boot项目中集成EMQX的MQTT客户端,并配置内置用户认证机制,确保消息通信的安全性。通过实战示例展示了从基础配置到高级功能的完整实现,包括连接管理、消息处理、动态订阅和TLS加密等关键环节,帮助开发者快速构建安全可靠的物联网应用。

weixin_30839881的博客 382

【SpringBoot深入浅出系列】SpringBoot之集成JWT实现token验证

文章目录一、JWT 是什么?二、为什么使用 JWT?1.支持跨域访问2.无状态3.更适用CDN4.更适用于移动端5.无需考虑CSRF三、何时使用 JWT?1.授权2.信息交换四、JWT 结构1.标头(header)2.有效载荷(payload)3.签名(Signature)五、创建项目集成 JWT 实现 token 验证1.项目说明2.创建 Spring Initializr 项目 jwt(1).添加依赖(2).添加配置(3).新建实体类 User(4).新建 JWT 工具类 JwtUtils(5).新建控

邓邓子的博客 2631

敏感数据传输安全:加密算法选择与Java代码实现实战

在应用开发中,数据安全传输是保障用户隐私和业务合规的基石,其核心目标包括机密性、完整性和不可否认性。为实现这些目标,开发者需要深入理解并正确应用加密算法、哈希算法和数字签名等技术原理。例如,对称加密算法AES用于高效加密大量数据,而非对称加密算法RSA则解决了密钥分发难题,两者常结合使用以兼顾安全与效率。在工程实践中,算法的选择与组合需紧密结合具体场景,如API接口传输、数据库字段存储等。本文以金融支付等典型场景为例,深入探讨了如何避免常见安全陷阱,例如弃用不安全的ECB模式、采用AES-GCM认证加密模式

470

Springboot整合Spring security+Oauth2+JWT搭建认证服务器,网关,微服务之间权限认证及授权

一、 单点登录 1、单点登录技术方案 二、 第三方认证 1、 Oauth2认证 2、 Oauth2的应用场景 三、 Spring security Oauth2认证 1、 JWT (一) 、令牌结构 (二) 、生成私钥和公钥 (1)、生成密钥证书 (2)、查询证书信息 (3)、删除别名 (4)、导出公钥 2、 搭建Spring security认证服务器 (一)、导入Spring Security...

csweldn520的专栏 8846

SpringBoot实战:构建安全试卷加密存档系统(毕设项目详解)

在Java Web开发领域,SpringBoot框架以其快速启动和约定大于配置的理念,成为构建企业级应用的首选。其核心原理是通过自动配置和起步依赖,简化了传统Spring应用的复杂配置,使开发者能聚焦业务逻辑实现。这一技术价值在于大幅提升了开发效率,降低了项目维护成本,尤其适用于需要快速迭代的Web应用场景。结合数据安全这一关键需求,对称加密算法AES在保障文件机密性方面扮演着核心角色。通过AES-GCM等认证加密模式,不仅能实现高效加密,还能确保数据完整性,防止篡改。这些技术在教育信息化、文档安全管理等场

dianwei5413的博客 390

sha-256加密

sha-256加密 包含md5 加密

SQLSTATE58030

在优化一条SQL的时候遇到了执行错误 gtlions =# select t1.telnumber,t2.ua,t2.url,t1.apply_name,t2.apply_name from tb1 t1 gtlions -# left outer join tb2 t2 on t1.sid = t2.ipsid gtlions-# where t1.sum_date=20141128 a

Gtlions Tracker 3659

OpenSSH服务器安全配置避坑指南:从KexAlgorithms到完整sshd_config调优

本文详细介绍了OpenSSH服务器的安全配置方法,重点从KexAlgorithms密钥交换算法优化入手,提供完整的sshd_config调优指南。内容包括加密算法加固、登录控制设置、高级防护策略以及跨发行版兼容性处理,帮助管理员有效防范SSH安全风险,避免常见配置陷阱。

weixin_30603633的博客 427

ABtest描述统计功效

我们在面试数据分析时,常常会问到如何确定样本量的问题,会有一个指标:统计功效(power),或者是1-β 统计功效会影响实验的可信度,甚至会影响实验所需的样本量,要了解统计功效,首先要理解两类统计错误 假如我们做了一个AB实验,且两组用户的数据均值为μ1和μ2,我们会有两个初始假设: H0:两个实验组的数据没有差别(μ1=μ2),这个假设也叫“零假设”,也叫原假设 H1:两个实验组之间的数据存在差别(μ1≠μ2),这个假设也叫“非零假设”,也叫备择假设 定义两类错误: 实验本身没有效应,但我们觉

qq_38134556的博客 898

java springboot3.x jwt+spring security6.x实现用户登录认证

springboot3.x +jwt +spring Security实现用户登录认证,为什么需要jwt 为什么需要spring Security 他们的关系,作用是什么,以及怎么实现

Leaf吧的博客 1942

稳定双共轭梯度法BiCGSTAB流程

稳定双共轭梯度法BiCGSTAB流程

abner361的博客 1154

YOLOv13改进策略【特征提取层】| 引入注意力卷积模块RFAConv,关注感受野空间特征 助力yolov13精度提升

RFAConv:创新空间注意力和标准卷积运算感受野空间特征是针对卷积核设计的,根据卷积核大小动态生成。以3×3卷积核为例,它由非重叠滑动窗口组成,每个窗口代表一个感受野滑块。

Limiiiing的博客 359

SpringSecurity的使用

(1)在之前的单体架构时代,我们认证成功之后都会将信息存入到Session中,然后响应给客户端的是对应的Session中数据的key,客户端会将这个key存储在cookie中,之后请求都会携带这个cookie中的信息,结构图如下:(2)但是随着技术的更新迭代,我们在项目架构的时候更多的情况下会选择前后端分离或者分布式架构,那么在这种情况下基于session的认证方式就显露了很多的不足,列举几个明显的特点:①cookie存储的内容有限制4k。

y516369的博客 845

ESP32-IDF开发之旅 基础篇⑨ ESP-IDF的FreeRTOS任务间通信和同步

本文介绍了FreeRTOS任务间通信中的队列机制,重点讲解了队列的创建、发送和接收数据的API使用方法。文章提供了详细的技术说明和示例代码,包括xQueueCreate、xQueueSend、xQueueReceive等核心函数的参数说明和返回值解释。通过一个2生产者+1消费者的实际案例,展示了如何在ESP-IDF环境下使用FreeRTOS队列实现任务间通信。示例中包含了数据发送失败处理和接收数据验证等实用技巧,为开发者提供了可参考的实现模式。

单片机菜鸟哥的博客 427
上一篇: 服务器迁移导致的C3P0连接池死锁问题
下一篇: Spring Boot学习笔记(一)
CodersCoder
博客等级 码龄10年 90粉丝 258原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值