# 全国企业采购交易寻源询价系统开放平台签名说明


# 平台向三方系统推送信息或第三方向平台接口发起GET请求时,会对请求参数进行签名,业务系统收到请求后需要先对签名进行校验,签名校验规则如下

  • 每次一个签名必须有个时间戳(timestamp)参与签名,时间戳格式为秒值。与请求的时间的时间差不能大于 5 分钟。

      如:ts=1655864789
    
  • 将除sign之外的所有参数先按参数名称字母顺序由小到大排列

  • 将排序的参数以key-value形式拼接成字符串 (如果value值为null,将视为空值)。key与value之间使用“=”拼接,各参数之间使用“&”连接。 请注意将时间转换为:yyyy-MM-dd HH:mm:ss格式字符串
    如:param1=val1&param2=val2&ts=1655864789

  • 将pushToken拼接在最后

      如: pushToken="test-3920f23f2j"
          param1=val1&param2=val2&ts=1655864789
    
  • 将拼接后的字符串进行三次MD5+盐(pushToken)运算,即可得到签名值, md5为32小写。

  String s1 = toMD5(paramStr + pushToken);
  String s2 = toMD5(s1 + pushToken);
  String s3 = toMD5(s2 + pushToken);
1
2
3

# 生产签名算法java代码示例如下

/**
 * 需要签名的参数
 * @param objMap
 * @return String
 */
private String createSign(Map<String, Object> objMap){
    String pushToken = "vnkle90er78";
    //参数进行排序,排除值为null的参数
    StringBuilder buff = new StringBuilder();
    String planttext = objMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .collect(
                    ()-> buff,
                    (buf,entry)->{
                        if (ObjectUtils.isEmpty(entry.getValue())){
                            buf.append(entry.getKey()).append("=").append("&");
                        }else {
                            buf.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                        }
                    },
                    (buf1,buf2)->{}
            ).toString();
    String paramStr = planttext.substring(0, planttext.length() - 1);
    System.out.println(paramStr);
    System.out.println(paramStr + pushToken);
    //进行MD5三次加密
    String s1 = toMD5(paramStr + pushToken);
    String s2 = toMD5(s1 + pushToken);
    String s3 = toMD5(s2 + pushToken);
    System.out.println(s3);
    return s3;
}

/**
 * 生成MD5
 * @param s 需要加密的字符串
 * @return
 */
private String toMD5(String s){
    MessageDigest algorithm;
    try
    {
        algorithm = MessageDigest.getInstance("MD5");
        algorithm.reset();
        algorithm.update(s.getBytes("UTF-8"));
        byte[] messageDigest = algorithm.digest();
        if (messageDigest == null)
        {
            return null;
        }
        StringBuffer buf = new StringBuffer(messageDigest.length * 2);
        int i;

        for (i = 0; i < messageDigest.length; i++)
        {
            if ((messageDigest[i] & 0xff) < 0x10)
            {
                buf.append("0");
            }
            buf.append(Long.toString(messageDigest[i] & 0xff, 16));
        }
        return buf.toString();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return null;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

MD5算法校准值如下

MD5("123456") = "e10adc3949ba59abbe56e057f20f883e";
1
上一次更新时间: 10/17/2022, 3:10:52 PM