Operation methods for adding and verifying signatures on Java HTTP interface
1. Business background
Recently, I contacted some e-commerce businesses and found that when dealing with e-commerce business interfaces, such as Taobao and payment interfaces, both sides of the interface need to sign the interface data in order to ensure that the data parameters have not been tampered during transmission, and then verify the interface parameters at the interface server to ensure that the two signatures are the same, Business logic processing can be performed after the signature verification is passed. Here we mainly introduce the processing ideas. As for the signature algorithm, I won't introduce it too much. There are a lot of them on the Internet.
2. Processing ideas
Both parties agree that the parameters are arranged in a specific order, such as alphabetical order, such as URL: http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX (signature is the incoming signature). After you get the input parameter, add the parameter string a = wersd & B = sd2354 & C = 4 with MD5 according to your agreed signature rules, and then compare it with the signature value of the input parameter to confirm whether the caller is legal. This is the idea of interface signature verification.
3. Example exercise
After communication, both parties of the interface have reached the following consensus on the interface:
1. Precautions mainly refer to the description of interface protocol, incoming parameter type, signature algorithm, file format, etc
2. The following is a real case of e-commerce business interface. Both parties have agreed on the interface URL, business parameters, fixed parameters, signature and return data format
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; } }