身边云服务商系统API

API文档示例


数字签名

<h2>签名</h2> <p>平台通过验证数字签名来保证请求的真实性和数据的完整性。</p> <h3>请求签名</h3> <p>应用需要使用平台分配的签名key以MD5的方式对消息体进行签名。请求的签名信息通过参数<code>sign</code> 传递。没有携带签名或者签名验证不通过的请求,都不会被执行,并返回<code>401 Unauthorized</code> 。</p> <h3>应答签名</h3> <p>对于签名验证成功的请求,平台同样会使用对应的签名key以MD5的方式对应答进行签名。签名的信息包含响应参数<code>sign</code>里。</p> <p>没有携带签名的成功应答(HTTP状态码为2xx),应认为是伪造或被篡改的应答。</p> <h3>签名规则</h3> <p>(1) 将原始的请求参数(或响应参数)列表,排除掉不包含值的参数和sign参数。 (2) 对参数名称按照升序排序,然后依次拼接参数值,最后在尾部拼接上签名key,得到签名原串plainText。 (3) 对plainText做MD5得到摘要字节数组,对字节数组做十六进制转码,得到字符串,作为签名参数<code>sign</code>的值。</p> <p><code>注:如果包含敏感数据,例如密码、手机号,会先加密,再做生成签名的处理</code></p> <h3>签名示例</h3> <pre><code>import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.MessageDigest; import java.util.*; public class MD5SignUtils { private static final Logger LOG = LoggerFactory.getLogger(MD5SignUtils.class); /** * 获取签名 * * @param param * @return */ public static String getSign(String md5Key, Map&lt;String, String&gt; param) { try { return _md5Encode(getSignPlainText(md5Key, param)); } catch (Exception e) { LOG.error("签名错误", e); return "ERROR"; } } /** * 验签 * * @param signKey * @param param * @return */ public static boolean verifySign(String signKey, Map&lt;String, String&gt; param) { String sign = param.get("sign"); param.remove("sign"); String verifySign = getSign(signKey, param); if (verifySign.equals(sign)) { LOG.info("验签通过"); return true; } else { LOG.info("验签失败"); return false; } } public static String getSignPlainText(String md5Key, Map&lt;String, String&gt; param) { try { if (param.get("sign") != null) { param.remove("sign"); } List arrayList = new ArrayList(param.entrySet()); Collections.sort(arrayList, new Comparator() { public int compare(Object o1, Object o2) { Map.Entry obj1 = (Map.Entry) o1; Map.Entry obj2 = (Map.Entry) o2; return (obj1.getKey()).toString().compareTo((String) obj2.getKey()); } }); StringBuilder md5keyBuilder = new StringBuilder(""); for (Iterator iter = arrayList.iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); String value = String.valueOf(entry.getValue()); if (StringUtils.isEmpty(value) || value.equals("null")) { continue; } md5keyBuilder.append(value); } md5keyBuilder.append(md5Key); // LOG.info("签名参数:" + md5key); return md5keyBuilder.toString(); } catch (Exception e) { LOG.error("组装签名参数错误", e); return "ERROR"; } } /** * MD5加密 生成32位md5码 * * @param inStr 待加密字符串 * @return 返回32位md5码 */ public static String _md5Encode(String inStr) throws Exception { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] byteArray = inStr.getBytes("UTF-8"); byte[] md5Bytes = md5.digest(byteArray); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i &lt; md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) &amp; 0xff; if (val &lt; 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } }</code></pre>

页面列表

ITEM_HTML