Java Http接口加签、验签操作方法
|
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、业务参数、固定参数、签名以及返回数据格式
接口调用时,接口调用方代码如下(仅供参考):
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;
}
}
服务器端代码如下(仅供参考):
@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接口加签、验签操作方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |



