1、业务背景

最近接触了一些电商业务,发现在处理电商业务接口时,比如淘宝、支付类接口,接口双方为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确保两个签名是一样的,验签通过之后再进行业务逻辑处理。我们这里主要介绍一下处理思路,至于签名算法我不做过多介绍,网上一大堆。

2、处理思路

双方约定好,参数按特定顺序排列,比如按首字母的顺序排列,如url:http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX(signature为传入的签名),等你拿到入参后,将参数串a=wersd&b=sd2354&c=4按你们约定的签名规则,自己用md5加签一次,然后和入参的signature值对比,以确认调用者是否合法,这就是接口签名验证的思路。

3、实例练习

接口双方经过沟通,对接口达成如下共识:

1、注意事项,主要指接口的的协议、传入参数类型、签名算法、文件格式等说明

2、下面是一个电商业务接口的真实案例,双方约定好了接口URL、业务参数、固定参数、签名以及返回数据格式

接口调用时,接口调用方代码如下(仅供参考):
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.pcmall;
 
import java.io.BufferedReader;                 
import java.io.DataOutputStream;                   
import java.io.IOException;                
import java.io.InputStreamReader;                  
import java.io.UnsupportedEncodingException;                   
import java.net.HttpURLConnection;                 
import java.net.URL;                   
import java.net.URLEncoder;                
import java.security.MessageDigest;                
import java.security.NoSuchAlgorithmException;                 
import java.util.ArrayList;                
import java.util.Collections;                  
import java.util.Iterator;                 
import java.util.List;                 
import java.util.Map;                  
import java.util.TreeMap;
                     
public class APITest {                 
  static String TEST_URL = "待定";                   
  static String TEST_KEY = "待定";                   
  static String TEST_SEC = "待定";                   
                     
  public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {                   
    String result = getResult(TEST_URL, getReqParam());                
    System.out.print(result);                  
  }                
                     
  private static String getReqParam() throws UnsupportedEncodingException, NoSuchAlgorithmException {                  
    TreeMap<String, String> req = new TreeMap<String, String>();           
    req.put("a", TEST_KEY);                
    req.put("f", "json");                  
    req.put("l", "zh_CN");                 
    req.put("m", "zhongan.repair.query");                  
    req.put("v", "1.0");                   
    req.put("i", "" + System.currentTimeMillis() / 1000);                  
    req.put("params", "{\"assignNo\":\"TEST018\"}");                   
    req.put("s", sign(req, null, TEST_SEC));                   
                         
    StringBuilder param = new StringBuilder();                 
    for (Iterator<Map.Entry<String, String>> it = req.entrySet().iterator(); it.hasNext();) {                  
      Map.Entry<String, String> e = it.next();                   
      param.append("&").append(e.getKey()).append("=").append(URLEncoder.encode(e.getValue(), "UTF-8"));                   
    }                  
                         
    return param.toString().substring(1);                  
  }                
                     
  private static String sign(Map<String, String> paramValues, List<String> ignoreParamNames, String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException {                
    StringBuilder sb = new StringBuilder();                
    List<String> paramNames = new ArrayList<String>(paramValues.size());                   
    paramNames.addAll(paramValues.keySet());                   
    if (ignoreParamNames != null && ignoreParamNames.size() > 0) {                  
      for (String ignoreParamName : ignoreParamNames) {                
        paramNames.remove(ignoreParamName);                
      }                
    }                  
    Collections.sort(paramNames);                  
                         
    sb.append(secret);                 
    for (String paramName : paramNames) {                  
      sb.append(paramName).append(paramValues.get(paramName));                 
    }                  
    sb.append(secret);                 
                     
    MessageDigest md = MessageDigest.getInstance("SHA-1");                 
    return byte2hex(md.digest(sb.toString().getBytes("UTF-8")));                   
  }                
                     
  private static String byte2hex(byte[] bytes) {                   
    StringBuilder sign = new StringBuilder();                  
    for (int i = 0; i < bytes.length; i++) {                
      String hex = Integer.toHexString(bytes[i] & 0xFF);                   
      if (hex.length() == 1) {                 
        sign.append("0");                  
      }                
      sign.append(hex.toUpperCase());                  
    }                  
    return sign.toString();                
  }                
                     
  private static String getResult(String urlStr, String content) {                 
    URL url = null;                
    HttpURLConnection connection = null;                   
    try {                  
      url = new URL(urlStr);                   
      connection = (HttpURLConnection) url.openConnection();                   
      connection.setDoOutput(true);                
      connection.setDoInput(true);                 
      connection.setRequestMethod("POST");                 
      connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");                
      connection.setUseCaches(false);                  
      connection.connect();                
                         
      DataOutputStream out = new DataOutputStream(connection.getOutputStream());                   
      out.write(content.getBytes("UTF-8"));                
      out.flush();                 
      out.close();                 
                         
      BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));                 
      StringBuffer buffer = new StringBuffer();                
      String line = "";                
      while ((line = reader.readLine()) != null) {                 
        buffer.append(line);                   
      }                
      reader.close();                  
                     
      return buffer.toString();                
    } catch (IOException e) {                  
      e.printStackTrace();                 
    } finally {                
      if (connection != null) {                
        connection.disconnect();                   
      }                
    }                  
                         
    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
72
73
74
75
@RequestMapping("/repairTakeOrder")
    @ResponseBody
    public ResponseVO repairTakeOrder(@RequestBody String jsonStr) {
        logger.info("repairTakeOrder入参:" + jsonStr);
 
        ResponseVO responseVO = null;
        try {
            RepairOrder repairOrder = JackJsonUtil.toBean(jsonStr,
                    RepairOrder.class);
            TreeMap<String, String> paramsMap = new TreeMap<String, String>();
            paramsMap.put("gsxx01", repairOrder.getGsxx01());
            paramsMap.put("orderType", repairOrder.getOrderType().toString());
            paramsMap.put("serviceNo", repairOrder.getServiceNo());
            paramsMap.put("vipCard", repairOrder.getVipCard());
            paramsMap.put("customerName", repairOrder.getCustomerName());
            paramsMap.put("customerPhone", repairOrder.getCustomerPhone());
            paramsMap.put("customerTel", repairOrder.getCustomerTel());
            paramsMap.put("province", repairOrder.getProvince());
            paramsMap.put("city", repairOrder.getCity());
            paramsMap.put("county", repairOrder.getCounty());
            paramsMap.put("address", repairOrder.getAddress());
            paramsMap.put("salerCode", repairOrder.getSalerCode());
            paramsMap.put("salerName", repairOrder.getSalerName());
            paramsMap.put("storeCode", repairOrder.getStoreCode());
            paramsMap.put("storeName", repairOrder.getStoreName());
            paramsMap.put("site", repairOrder.getSite());
 
            paramsMap.put("siteDesp", repairOrder.getSiteDesp());
            paramsMap.put("engineerCode", repairOrder.getEngineerCode());
            paramsMap.put("engineerName", repairOrder.getEngineerName());
            if (repairOrder.getServiceDate() != null) {
                paramsMap.put("serviceDate",
                        DateUtils.formatDate(repairOrder.getServiceDate()));
            }
 
            if (repairOrder.getSalePrice() != null) {
                paramsMap.put("salePrice", repairOrder.getSalePrice()
                        .toString());
            }
 
            paramsMap.put("profitCenter", repairOrder.getProfitCenter());
            paramsMap.put("costCenter", repairOrder.getCostCenter());
            paramsMap.put("gsxx02", repairOrder.getGsxx02());
            paramsMap.put("returnReason", repairOrder.getReturnReason());
            if (repairOrder.getOriOrder() != null) {
                paramsMap.put("oriOrder", repairOrder.getOriOrder().toString());
            }
 
            if (repairOrder.getOriServiceNo() != null) {
                paramsMap.put("oriServiceNo", repairOrder.getOriServiceNo());
            }
 
            // 拼接签名原串(a=1&b=2)
            String paramSrc = RequestUtils.getParamSrc(paramsMap);
            logger.info("签名原串:" + paramSrc);
            //进行验签操作
            if (SignUtils.verifymd5(paramSrc, repairOrder.getSign())) {
                //处理业务逻辑
                responseVO=erpServiceImpl.repairTakeOrder(repairOrder);
                 
            } else {
                responseVO = new ResponseVO();
                responseVO.setSuccess(false);
                responseVO.setErrorMsg("验签失败");
            }
 
        } catch (Exception e) {
            logger.error("", e);
            responseVO = new ResponseVO();
            responseVO.setSuccess(false);
            responseVO.setErrorMsg(StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : "后台异常");
        }
        return responseVO;
 
    }

以上这篇Java Http接口加签、验签操作方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

Java Http接口加签、验签操作方法的更多相关文章

  1. RSA体系 c++/java相互进行加签验签--转

    在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java ...

  2. Java实现RSA密钥对并在加解密、加签验签中应用的实例

    一.项目结构 二.代码具体实现 1.密钥对生成的两种方式:一种生成公钥私文件,一种生成公钥私串 KeyPairGenUtil.java package com.wangjinxiang.genkey. ...

  3. java RSA 加签验签【转】

    引用自: http://blog.csdn.net/wangqiuyun/article/details/42143957/ java RSA 加签验签 package com.testdemo.co ...

  4. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

  5. RSA加密解密与加签验签

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年7月首次在美国公布 ...

  6. 微信小程序(17)-- RSA加密 解密 加签 验签

    RSA加密 解密 加签 验签 /** * 注:区分RSA私钥的类型,有pkcs1和pkcs8.pkcs8格式的私钥主要用于Java中 pkcs1格式: -----BEGIN RSA PRIVATE K ...

  7. Python rsa公私钥生成 rsa公钥加解密(分段加解密)-私钥加签验签实战

    一般现在的SAAS服务提供现在的sdk或api对接服务都涉及到一个身份验证和数据加密的问题.一般现在普遍的做法就是配置使用非对称加密的方式来解决这个问题,你持有SAAS公司的公钥,SAAS公司持有你的 ...

  8. 支付宝支付集成中:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过

    在做p2p配资平台,也就是公司的项目,遇到了一个问题:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过 下面是实录: 通知服务器的POST过来的数据: 1.si ...

  9. Java使用数字证书加密通信(加解密/加签验签)

    本文中使用的Base64Utils.java可参考:http://www.cnblogs.com/shindo/p/6346618.html 证书制作方法可参考:http://www.cnblogs. ...

随机推荐

  1. bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形

    USACO划水中... 题目中要求经过原点的三角形数目,但这种三角形没什么明显的特点并不好求,所以可以求不经过原点的三角形数量. 对于一个非法三角形,它离原点最近的那条边连接的两个点所连的两条边一定在 ...

  2. Stamp Rally

    Stamp Rally 最大值最小,可以二分,然后并查集看能不能到z个点 但是询问过多,并且发现每次二分要加入的点并不是所有的m条边 于是就考虑整体二分 并查集的处理是重点: 对于一般的dfs分治树, ...

  3. 【左偏树】【P3261】 [JLOI2015]城池攻占

    Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其 ...

  4. python检测服务器是否ping通

    好想在2014结束前再赶出个10篇博文来,~(>_<)~,不写博客真不是一个好兆头,至少说明对学习的欲望和对知识的研究都不是那么积极了,如果说这1天的时间我能赶出几篇精致的博文,你们信不信 ...

  5. 在ubuntu下安装opencv

    每次学习一个新的东西,最让气恼的也许就是库,软件之类的东西了把.本来以为再ubuntu虚拟机上照着网上的教程一步步做肯定一下子就弄好了,结果发现好多教程都有好多的坑,有些地方他们少一步你也不知道,有些 ...

  6. Python【zip-map-filter】三个内置函数

    print("============内置函数:zip===========")l2 = ['a','b','c','e','f','g']l3 = [1,2,3]L4=['A', ...

  7. SMO详解

    转自:简书https://www.jianshu.com/p/55458caf0814 SVM通常用对偶问题来求解,这样的好处有两个:1.变量只有N个(N为训练集中的样本个数),原始问题中的变量数量与 ...

  8. java基础-迭代器(Iterator)与增强for循环

    java基础-迭代器(Iterator)与增强for循环 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Iterator迭代器概述 Java中提供了很多个集合,它们在存储元素时 ...

  9. webpack的基础入门

    webpack的基础入门 这里对于 webpack 的基础入门进行一些总结,可以参考 github 上的 webpack-demo ,链接是 https://github.com/RealAndMe/ ...

  10. 如何创建一个 Lua 模块

    如何创建一个 Lua 模块 翻译自: How to Create a Lua Module 译者: FreeBlues 正文 Lua编程语言 中的一个 模块(module)是一个包含函数和变量的代码片 ...