首页 > 编程语言 >接口签名规则和Java实现签名和验签代码

接口签名规则和Java实现签名和验签代码

时间:2023-06-30 18:55:56浏览次数:30  
标签:map return String 和验 sign 签名 key Java

接口签名规则和Java实现签名和验签代码

签名规则
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证接口调用传送的sign参数不参与签名,将生成的签名与该sign值作校验。
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。 注意:密钥的长度为32个字节。

package com.example.core.mydemo.sign;

import com.example.core.mydemo.MD5;
import org.apache.commons.lang3.StringUtils;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


public class SignatureTest {

    /**
     * 签名
     * @param map
     * @param key
     * @return
     * @throws Exception
     */
    public static String getSign(Map<String,String> map,String key) throws Exception{
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,String> entry:map.entrySet()){
            if(entry.getValue() != null && StringUtils.isNotBlank(entry.getValue().toString()) && !"null".equals(entry.getValue())
            && !"class".equals(entry.getKey()) && !"data".equals(entry.getKey())){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        //过滤最后一个字符串&
        int lastIdx = result.lastIndexOf("&");
        result = result.substring(0,lastIdx);
        result +=  key;
        try{
            result = MD5.MD5Encode(result).toUpperCase();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 验证签名
     * @param map
     * @param key
     * @return
     * @throws Exception
     */
    public static boolean checkIsSignValidFromResponseString(Map<String,String> map,String key) throws Exception {
        String signFromAPIResponse = null;
        if(map.get("sign")!=null){
            signFromAPIResponse = map.get("sign").toString();
        }
        if(signFromAPIResponse=="" || signFromAPIResponse == null){
            return false;
        }
        map.put("sign","");
        map.put("class","");
        //重新签名
        String signForAPIResponse = SignatureTest.getSign(map,key);
        if(!signForAPIResponse.equals(signFromAPIResponse)){
            //签名验不过,表示这个API返回的数据有可能已经被篡改了
            return false;
        }
        return true;
    }

    
    public static void main(String[] args) {
        try {
            //key没有位数的要求
            String key = "1234567890tkltktqVdTstvuhlZHTest";

            //simple test
            Map<String,String> map = new HashMap<String,String>();
            map.put("appId", "0001");
            map.put("userName", "steve");
            map.put("pwd", "123456");
            map.put("sex", "man");
            String sign = SignatureTest.getSign(map,key);
            System.out.println(sign);

            map.put("sign", sign);

            //验证签名
            System.out.println(SignatureTest.checkIsSignValidFromResponseString(map,key));

        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}
package com.example.core.mydemo;

import java.security.MessageDigest;


public class MD5 {
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 转换字节数组为16进制字串
     * @param b 字节数组
     * @return 16进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }

    /**
     * 转换byte到16进制
     * @param b 要转换的byte
     * @return 16进制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * MD5编码
     * @param origin 原始字符串
     * @return 经过MD5加密之后的结果
     */
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

}

 

标签:map,return,String,和验,sign,签名,key,Java
From: https://www.cnblogs.com/oktokeep/p/17517631.html

相关文章

  • 2023.6.30//关于java链接SQLserver数据库报错:驱动程序无法通过使用安全套接字层(SSL)
    详情如下:驱动程序无法通过使用安全套接字层(SSL)加密与SQLServer建立安全连接。错误:“PKIXpathbuildingfailed:sun.security.provider.certpath.SunCertPathBuilderException:unabletofindvalidcertificationpathtorequestedtarget”。ClientConnectionId:32d1......
  • JavaScript aglo 算法 时间复杂度
    https://www.bigocheatsheet.com/https://www.hello-algo.com/chapter_preface/about_the_book/ gpt的回答好的,下面给出这些算法的JavaScript例子,并给出它们的时间复杂度分析:O(1)-常数时间复杂度:javascriptCopyCodefunctionconstantTimeAlgorithm(n){return2+......
  • laytpl( Layui 的一款轻量 JavaScript 模板引擎)html标签点击事件传递多参
     <scripttype="text/html"id="aobjectvalue_temp"><spanclass="us-font-blue"style="cursor:pointer"onclick="seeinfo('{{d.aobjectkey}}','{{d.atype}}')">[资源详情]</spa......
  • java操作redis
    加依赖<!--redis依赖--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency>pub......
  • Java中的反射机制
    一、反射简介(一)什么是反射​ Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射......
  • Java 网络爬虫,就是这么的简单
    是Java网络爬虫系列文章的第一篇,如果你还不知道Java网络爬虫系列文章,请参看学Java网络爬虫,需要哪些基础知识。第一篇是关于Java网络爬虫入门内容,在该篇中我们以采集虎扑列表新闻的新闻标题和详情页为例,需要提取的内容如下图所示: 我们需要提取图中圈出来的文字及其对......
  • 使用easy-captcha验证码出现javax. script ScriptEngine.eval(String)" because "engi
    1.问题java项目使用  ArithmeticCaptcha  验证码,出现javax.scriptScriptEngine.eval(String)"because"engine"isnulArithmeticCaptchacaptcha=newArithmeticCaptcha(111,36);<dependency><groupId>com.github.whvcse</groupId>......
  • Java PTA第4~5次题目集总结以及期中考试总结
    一.前言1.第四次题目集的知识点涉及Time类以及前面学的各种知识点;题量很少只有一题;难度比较大。2.第五次题目集的知识点主要是Time类、异常处理等等;题量很少只有一题;难度比较大。3.期中考试的知识点涉及类、继承与多态、接口等等;题量不多,一共4题;整体难度不高。二.设计与分析7......
  • JavaScript实现Fly Bird小游戏
    1.分析页面结构,理清需求和功能游戏有三个界面,分别是开始界面,游戏界面和游戏结束界面。1.1开始界面 游戏的大背景上下移动的游戏标题和翅膀摆动的小鸟start按钮,点击进入游戏界面一直移动的地面1.2游戏界面显示越过障碍数量的计分器移动的障碍物,分别是上管道和下......
  • JavaScript中数组常用方法汇总!
    数组是一个复杂数据类型,我们在操作它的时候就不能再想基本数据类型一样操作了。比如我们想改变一个数组//创建一个数组vararr=[1,2,3]//我们想把数组变成只有1和2arr=[1,2]这样肯定是不合理,因为这样不是在改变之前的数组。相当于重新制作了一个数组给到arr......