三 java 验签业务逻辑 ,

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、业务参数、固定参数、签名以及返回数据格式




接口调用时,接口调用方代码如下(仅供参考):
[java]  view plain  copy
  1. package com.pcmall;  
  2.   
  3. import java.io.BufferedReader;                    
  4. import java.io.DataOutputStream;                      
  5. import java.io.IOException;                   
  6. import java.io.InputStreamReader;                     
  7. import java.io.UnsupportedEncodingException;                      
  8. import java.net.HttpURLConnection;                    
  9. import java.net.URL;                      
  10. import java.net.URLEncoder;                   
  11. import java.security.MessageDigest;                   
  12. import java.security.NoSuchAlgorithmException;                    
  13. import java.util.ArrayList;                   
  14. import java.util.Collections;                     
  15. import java.util.Iterator;                    
  16. import java.util.List;                    
  17. import java.util.Map;                     
  18. import java.util.TreeMap;  
  19.                       
  20. public class APITest {                    
  21.     static String TEST_URL = "待定";                    
  22.     static String TEST_KEY = "待定";                    
  23.     static String TEST_SEC = "待定";                    
  24.                           
  25.     public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {                    
  26.         String result = getResult(TEST_URL, getReqParam());                   
  27.         System.out.print(result);                     
  28.     }                     
  29.                       
  30.     private static String getReqParam() throws UnsupportedEncodingException, NoSuchAlgorithmException {                   
  31.         TreeMap<String, String> req = new TreeMap<String, String>();              
  32.         req.put("a", TEST_KEY);                   
  33.         req.put("f""json");                     
  34.         req.put("l""zh_CN");                    
  35.         req.put("m""zhongan.repair.query");                     
  36.         req.put("v""1.0");                      
  37.         req.put("i""" + System.currentTimeMillis() / 1000);                     
  38.         req.put("params""{\"assignNo\":\"TEST018\"}");                      
  39.         req.put("s", sign(req, null, TEST_SEC));                      
  40.                               
  41.         StringBuilder param = new StringBuilder();                    
  42.         for (Iterator<Map.Entry<String, String>> it = req.entrySet().iterator(); it.hasNext();) {                     
  43.             Map.Entry<String, String> e = it.next();                    
  44.             param.append("&").append(e.getKey()).append("=").append(URLEncoder.encode(e.getValue(), "UTF-8"));                    
  45.         }                     
  46.                               
  47.         return param.toString().substring(1);                     
  48.     }                     
  49.                           
  50.     private static String sign(Map<String, String> paramValues, List<String> ignoreParamNames, String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException {                     
  51.         StringBuilder sb = new StringBuilder();                   
  52.         List<String> paramNames = new ArrayList<String>(paramValues.size());                      
  53.         paramNames.addAll(paramValues.keySet());                      
  54.         if (ignoreParamNames != null && ignoreParamNames.size() > 0) {                     
  55.             for (String ignoreParamName : ignoreParamNames) {                     
  56.                 paramNames.remove(ignoreParamName);                   
  57.             }                     
  58.         }                     
  59.         Collections.sort(paramNames);                     
  60.                               
  61.         sb.append(secret);                    
  62.         for (String paramName : paramNames) {                     
  63.             sb.append(paramName).append(paramValues.get(paramName));                      
  64.         }                     
  65.         sb.append(secret);                    
  66.                       
  67.         MessageDigest md = MessageDigest.getInstance("SHA-1");                    
  68.         return byte2hex(md.digest(sb.toString().getBytes("UTF-8")));                      
  69.     }                     
  70.                           
  71.     private static String byte2hex(byte[] bytes) {                    
  72.         StringBuilder sign = new StringBuilder();                     
  73.         for (int i = 0; i < bytes.length; i++) {                   
  74.             String hex = Integer.toHexString(bytes[i] & 0xFF);                    
  75.             if (hex.length() == 1) {                      
  76.                 sign.append("0");                     
  77.             }                     
  78.             sign.append(hex.toUpperCase());                   
  79.         }                     
  80.         return sign.toString();                   
  81.     }                     
  82.                           
  83.     private static String getResult(String urlStr, String content) {                      
  84.         URL url = null;                   
  85.         HttpURLConnection connection = null;                      
  86.         try {                     
  87.             url = new URL(urlStr);                    
  88.             connection = (HttpURLConnection) url.openConnection();                    
  89.             connection.setDoOutput(true);                     
  90.             connection.setDoInput(true);                      
  91.             connection.setRequestMethod("POST");                      
  92.             connection.setRequestProperty("Content-Type""application/x-www-form-urlencoded;charset=UTF-8");                     
  93.             connection.setUseCaches(false);                   
  94.             connection.connect();                     
  95.                                   
  96.             DataOutputStream out = new DataOutputStream(connection.getOutputStream());                    
  97.             out.write(content.getBytes("UTF-8"));                     
  98.             out.flush();                      
  99.             out.close();                      
  100.                                   
  101.             BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));                      
  102.             StringBuffer buffer = new StringBuffer();                     
  103.             String line = "";                     
  104.             while ((line = reader.readLine()) != null) {                      
  105.                 buffer.append(line);                      
  106.             }                     
  107.             reader.close();                   
  108.                       
  109.             return buffer.toString();                     
  110.         } catch (IOException e) {                     
  111.             e.printStackTrace();                      
  112.         } finally {                   
  113.             if (connection != null) {                     
  114.                 connection.disconnect();                      
  115.             }                     
  116.         }                     
  117.                               
  118.         return null;                      
  119.     }     
  120.       
  121.       
  122. }                 
服务器端代码如下(仅供参考):
[java]  view plain  copy
  1. @RequestMapping("/repairTakeOrder")  
  2.     @ResponseBody  
  3.     public ResponseVO repairTakeOrder(@RequestBody String jsonStr) {  
  4.         logger.info("repairTakeOrder入参:" + jsonStr);  
  5.   
  6.         ResponseVO responseVO = null;  
  7.         try {  
  8.             RepairOrder repairOrder = JackJsonUtil.toBean(jsonStr,  
  9.                     RepairOrder.class);  
  10.             TreeMap<String, String> paramsMap = new TreeMap<String, String>();  
  11.             paramsMap.put("gsxx01", repairOrder.getGsxx01());  
  12.             paramsMap.put("orderType", repairOrder.getOrderType().toString());  
  13.             paramsMap.put("serviceNo", repairOrder.getServiceNo());  
  14.             paramsMap.put("vipCard", repairOrder.getVipCard());  
  15.             paramsMap.put("customerName", repairOrder.getCustomerName());  
  16.             paramsMap.put("customerPhone", repairOrder.getCustomerPhone());  
  17.             paramsMap.put("customerTel", repairOrder.getCustomerTel());  
  18.             paramsMap.put("province", repairOrder.getProvince());  
  19.             paramsMap.put("city", repairOrder.getCity());  
  20.             paramsMap.put("county", repairOrder.getCounty());  
  21.             paramsMap.put("address", repairOrder.getAddress());  
  22.             paramsMap.put("salerCode", repairOrder.getSalerCode());  
  23.             paramsMap.put("salerName", repairOrder.getSalerName());  
  24.             paramsMap.put("storeCode", repairOrder.getStoreCode());  
  25.             paramsMap.put("storeName", repairOrder.getStoreName());  
  26.             paramsMap.put("site", repairOrder.getSite());  
  27.   
  28.             paramsMap.put("siteDesp", repairOrder.getSiteDesp());  
  29.             paramsMap.put("engineerCode", repairOrder.getEngineerCode());  
  30.             paramsMap.put("engineerName", repairOrder.getEngineerName());  
  31.             if (repairOrder.getServiceDate() != null) {  
  32.                 paramsMap.put("serviceDate",  
  33.                         DateUtils.formatDate(repairOrder.getServiceDate()));  
  34.             }  
  35.   
  36.             if (repairOrder.getSalePrice() != null) {  
  37.                 paramsMap.put("salePrice", repairOrder.getSalePrice()  
  38.                         .toString());  
  39.             }  
  40.   
  41.             paramsMap.put("profitCenter", repairOrder.getProfitCenter());  
  42.             paramsMap.put("costCenter", repairOrder.getCostCenter());  
  43.             paramsMap.put("gsxx02", repairOrder.getGsxx02());  
  44.             paramsMap.put("returnReason", repairOrder.getReturnReason());  
  45.             if (repairOrder.getOriOrder() != null) {  
  46.                 paramsMap.put("oriOrder", repairOrder.getOriOrder().toString());  
  47.             }  
  48.   
  49.             if (repairOrder.getOriServiceNo() != null) {  
  50.                 paramsMap.put("oriServiceNo", repairOrder.getOriServiceNo());  
  51.             }  
  52.   
  53.             // 拼接签名原串(a=1&b=2)  
  54.             String paramSrc = RequestUtils.getParamSrc(paramsMap);  
  55.             logger.info("签名原串:" + paramSrc);  
  56.             //进行验签操作  
  57.             if (SignUtils.verifymd5(paramSrc, repairOrder.getSign())) {  
  58.                 //处理业务逻辑  
  59.                 responseVO=erpServiceImpl.repairTakeOrder(repairOrder);  
  60.                   
  61.             } else {  
  62.                 responseVO = new ResponseVO();  
  63.                 responseVO.setSuccess(false);  
  64.                 responseVO.setErrorMsg("验签失败");  
  65.             }  
  66.   
  67.         } catch (Exception e) {  
  68.             logger.error("", e);  
  69.             responseVO = new ResponseVO();  
  70.             responseVO.setSuccess(false);  
  71.             responseVO.setErrorMsg(StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : "后台异常");  
  72.         }  
  73.         return responseVO;  
  74.   
  75.     }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值