iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java实现APIsign签名校验的方法详解
  • 654
分享到

Java实现APIsign签名校验的方法详解

2024-04-02 19:04:59 654人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 前言2. 签名生成策略3. api 签名算法 Java 实现4. 测试一下1. 前言 目的:为防止中间人攻击。 场景: 项目内部前后端调用,这种场景只需要做普通参数的签名校

1. 前言

目的:为防止中间人攻击。

场景:

  • 项目内部前后端调用,这种场景只需要做普通参数的签名校验和过期请求校验,目的是为了防止攻击者劫持请求 url 后非法请求接口。
  • 开放平台向第三方应用提供能力,这种场景除了普通参数校验和请求过期校验外,还要考虑 3D 应用的授权机制,不被授权的应用就算传入了合法的参数也不能被允许请求成功。

2. 签名生成策略

接下来详述场景 2,其实场景 1 也包含在场景 2 内部。

1.举例请求 url:

Http://api.abc.com/a-service/orders?orderType=1001&requestFrom=iOS&pageNum=2&pageSize=10

请求参数为:

参数名位置备注举例
X-Access-Keyheader客户端授权码,服务端提供,和 accessSecret 配对(场景 1 无此参数)app1
X-Access-Tokenheader当前登录用户 tokend7b5808c3f443eb5a496225468c7e4a5
X-UTCTimeheader当前发送请求时的时间2022-02-16T09:12:43.083Z
X-Randomheader请求随机数341be97d9aff90c9978347f66f945b77
orderTypequery订单类型1001
requestFromquery订单来源ioS
pageNumquery分页参数10
pageSizequery分页参数2

2.设原始参数为 stringA,stringA 中添加 X-Access-Key、X-UTCTime、X-Random 固定参数,将 stringA 内非空参数值和 header 的参数按照参数名 ASCII 码从小到大排序(字典序),使用 URL 键值对的格式(即 key1=value1&key2=value2…)拼接成字符串 stringB。

注意如下规则:

  • 参数名 ASCII 码从小到大排序(字典序);
  • 如果参数的值为空不参与签名;
  • 参数名区分大小写;
  • 验证调用返回或主动通知签名时,传送的 sign 参数不参与签名,将生成的签名与该 sign 值作校验。
// 最终拼接为stringB:
orderType=1001X-UTCTime=2022-02-16T09:12:43.083ZpageSize=10X-Access-Key=app1X-Access-Token=d7b5808c3f443eb5a496225468c7e4a5pageNum=2requestFrom=IOSX-Random=341be97d9aff90c9978347f66f945b77

3.在 stringB 最后拼接上 accessSecret (密钥) 得到 strinGC 字符串,并对 stringC 进行 MD5 运算,得到 sign 值。

// 最后拼上accessSecret得到stringC:
orderType=1001X-UTCTime=2022-02-16T09:12:43.083ZpageSize=10X-Access-Key=app1X-Access-Token=d7b5808c3f443eb5a496225468c7e4a5pageNum=2requestFrom=IOSX-Random=341be97d9aff90c9978347f66f945b77&accessSecret=192006250b4c09247ec02edce69f6a2d
// md5加密得到最终签名结果sign:
sign=e1a4907ef03adee3fa8d395552814f4e

4.将原始的请求 url 拼接上 sign 形成最终的请求 url。

http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10&sign=0f5a3cc534961d129a25d52d7ed8d003

5.最终请求 url 如下:

http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10&sign=0f5a3cc534961d129a25d52d7ed8d003

参数名位置备注举例
X-Access-Keyheader客户端授权码,服务端提供,和 accessSecret 配对(场景 1 无此参数)app1
X-Access-Tokenheader当前登录用户 tokend7b5808c3f443eb5a496225468c7e4a5
X-UTCTimeheader当前发送请求时的时间2022-02-16T09:12:43.083Z
X-Randomheader请求随机数341be97d9aff90c9978347f66f945b77
orderTypequery订单类型1001
requestFromquery订单来源IOS
pageNumquery分页参数10
pageSizequery分页参数2

6.服务端 gateway 同样做 sign 签名加密和校验,如果校验不通过则说明请求非法,直接拒绝,通过则下发到业务服务进行正常请求处理。

3. API 签名算法 Java 实现

public class SignUtil {

    
    public static <T> String sign(String accessSecret, String url, Map<String, Object> headers, T body) throws IllegalAccessException {
        Map<String, Object> signMap = new HashMap<>();
        if (headers != null) {
            signMap.putAll(headers);
        }
        Map<String, Object> paramMap = getUrlParams(url);
        if (paramMap != null) {
            signMap.putAll(paramMap);
        }
        Map<String, Object> bodyMap = getBodyParams(body);
        if (bodyMap != null) {
            signMap.putAll(bodyMap);
        }

        StringBuffer sb = new StringBuffer();
        signMap.forEach((k, v) -> {
            sb.append(k).append("=").append(v).append("&");
        });
        sb.append("accessSecret=").append(accessSecret);
        return stringToMD5(sb.toString());
    }

    private static Map<String, Object> getUrlParams(String url) {
        if (StringUtils.isBlank(url) || !url.contains("?")) {
            return null;
        }
        Map<String, Object> paramMap = new HashMap<>();
        String params = url.split("\\?")[1];
        for (String param : params.split("&")) {
            String[] p = param.split("=");
            paramMap.put(p[0], p[1]);
        }
        return paramMap;
    }

    private static <T> Map<String, Object> getBodyParams(T body) throws IllegalAccessException {
        if (body == null) {
            return null;
        }
        Map<String, Object> bodyMap = new HashMap<>();
        for (Field field : body.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            bodyMap.put(field.getName(), field.get(body));
        }
        return bodyMap;
    }

    private static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes());
        } catch (NoSuchAlGorithmException e) {
            throw new RuntimeException("没有这个md5算法!");
        }

        return new BigInteger(1, secretBytes).toString(16);
    }
}

4. 测试一下

public class App {
    public static void main(String[] args) throws IllegalAccessException {
        String url = "http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10";
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("X-Access-Key", "app1");
        headerMap.put("X-Access-Token", "d7b5808c3f443eb5a496225468c7e4a5");
        headerMap.put("X-UTCTime", generateDate());
        headerMap.put("X-Random", "341be97d9aff90c9978347f66f945b77");
        BodyVO body = new BodyVO(100000001L, "yangcan", new Date());

        String sign = SignUtil.sign("sdfsdfdsfdsfds", url, headerMap, body);
        System.out.println(sign);
    }

    
    private static String generateDate() {
        Date now = new Date();
        DateFORMat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
        return format.format(now);
    }

    @Data
    @AllArgsConstructor
    public static class BodyVO {
        private Long ycId;
        private String ycName;
        private Date ycTime;
    }
}

输出:

sign = 4f52eb34b30129a8d511dc803044086b

到此这篇关于Java实现API sign签名校验的方法详解的文章就介绍到这了,更多相关Java API签名校验内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java实现APIsign签名校验的方法详解

本文链接: https://www.lsjlt.com/news/154175.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java实现APIsign签名校验的方法详解
    目录1. 前言2. 签名生成策略3. API 签名算法 Java 实现4. 测试一下1. 前言 目的:为防止中间人攻击。 场景: 项目内部前后端调用,这种场景只需要做普通参数的签名校...
    99+
    2024-04-02
  • java签名校验功能怎么实现
    要实现Java签名校验功能,你可以按照以下步骤进行: 获取签名证书:首先,你需要获取要校验的文件的签名证书。可以使用Java的Ke...
    99+
    2023-10-26
    java
  • Java实现优雅的参数校验方法详解
    目录一、引子二、如何优雅地校验参数2.1 官方指导意见2.2 注解用法说明一、引子 要对方法的参数进行校验,最简单暴力的写法是这个样子: public static void...
    99+
    2024-04-02
  • android签名校验功能怎么实现
    要实现Android签名校验功能,可以按照以下步骤进行:1. 获取应用的签名信息:首先,获取应用的签名信息。可以通过以下代码获取应用...
    99+
    2023-08-23
    android
  • 详解Java如何实现数值校验的算法
    给定一个字符串如何判断它是否为数值类型?例如:字符串+100、5e2、-123、3.1416以及-1E-16都表示数值,为数值类型,但12e、1a3.14、1.2.3、+-5以及12...
    99+
    2024-04-02
  • Java实现验证文件名有效性的方法详解
    目录使用java.io.File使用 NIO2 API自定义的实现使用String.contains正则表达式模式匹配总结在本文中,我们将讨论使用 Java 验证一个给定的字符串是否...
    99+
    2024-04-02
  • 详解Java接口签名(Signature)实现方案
    目录一、要求二、流程三、实现大家好,我是程序员田同学! 今天上午收到一个需求,针对当前的系统开发一个对外开放的接口。 既然是对外开放,那么调用者一定没有我们系统的Token,就需要对...
    99+
    2024-04-02
  • Java实现添加、验证PDF数字签名的方法示例
    目录Jar文件获取及导入方法:在设置文档内容保护的方法中,除了对文档加密、添加水印外,应用数字签名也是一种有效防伪手段。数字签名的文件比较容易验证,并且具有较高的权威性和可信度。在P...
    99+
    2024-04-02
  • Java基于BC包的实现SM2签名验签方案,以及SM2签名中bc包冲突的部分解决方法
    信创改造也有一段时间了,这里记录和总结一些关于SM2算法的知识点。 1. pom.xml org.bouncycastle bcprov-jdk15on 1.57 或 or...
    99+
    2023-08-19
    java 算法
  • C#实现的4种常用数据校验方法小结(CRC校验,LRC校验,BCC校验,累加和校验)
    CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)...
    99+
    2024-04-02
  • java开发validate方法中校验工具类详解
    validate方法中校验工具类 日常Java开发中,我们使用validate的校验是很方便的,但是也有一些特殊情况需要单独处理, 例如:导入Excel校验,传入的是Multipa...
    99+
    2024-04-02
  • SpringBoot进行参数校验的方法详解
    目录介绍1.SpringBoot中集成参数校验1.1引入依赖1.2定义参数实体类1.3定义校验类进行测试1.4打开接口文档模拟提交数据2.参数异常加入全局异常处理器3.自定义参数校验...
    99+
    2024-04-02
  • SpringBoot自定义注解实现Token校验的方法
    1.定义Token的注解,需要Token校验的接口,方法上加上此注解 import java.lang.annotation.ElementType; import java.l...
    99+
    2024-04-02
  • SpringBootcontroller参数校验方法详细讲解
    目录单参数校验实体类校验分组校验嵌套校验自定义注解参数校验主要使用两个标签@Validated和@Valid; @Valid是Hibernate的注解校验,@Validated是sp...
    99+
    2023-01-17
    SpringBoot controller参数校验 SpringBoot controller
  • element多个表单校验的实现方法
    这篇文章给大家分享的是有关element多个表单校验的实现方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在项目中,经常会遇到表单检验,单个表单检验可查看element的官网文档,里面有详细的介绍。在这里我分享...
    99+
    2023-06-15
  • SpringBoot 中使用 Validation 校验参数的方法详解
    目录1. Validation 介绍1.1 Validation 注解1.2 @valid 和 @validated的区别2. SpringBoot 中使用 Validator 校验...
    99+
    2024-04-02
  • GoFrame实现顺序性校验示例详解
    目录引言基本介绍无序的原因顺序校验总结引言 在上一篇文章中 GoFrame数据校验之校验结果 | Error接口对象 ,关于顺序与非顺序性校验没有做充分的介绍。 这篇文章填上之前留的...
    99+
    2024-04-02
  • Java JWT实现跨域身份验证方法详解
    目录1、JWT简介2、JWT的结构2.1 头部(header)2.2 载荷(payload)2.3 签证(signature)3、JWT的原则4、JWT的用法5、JWT的问题和趋势6...
    99+
    2024-04-02
  • Ajax校验用户名是否存在的方法
    本文实例为大家分享了Ajax验证用户名是否存在的实例代码,代码简单易懂,非常不错,需要的朋友可以参考下 jsp页面 我引入了bootstrap和jQuery <div cl...
    99+
    2024-04-02
  • java签名实现的方式有哪些
    Java签名实现的方式有以下几种: 数字签名:使用非对称加密算法,如RSA或DSA,生成一个数字签名,用于验证数据的完整性和认证发...
    99+
    2023-10-26
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作