众包系统接口调用流程
<h4>接入椿耀平台</h4>
<hr />
<p>椿耀平台分发以下数据,作为请求的握手凭证</p>
<p>access_key: 接入身份标识
shipper_code: 注册公司标识
secret: 密钥,例 mUPNIDoUbsXcQF9Qtm3UnA==</p>
<h4>公共参数</h4>
<hr />
<p>公共参数是调用任何API都需传入的参数,目前支持的公共参数有:</p>
<table>
<thead>
<tr>
<th style="text-align: left;">名称</th>
<th style="text-align: left;">类型</th>
<th style="text-align: left;">是否必须</th>
<th style="text-align: left;">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">access_key</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;">是</td>
<td style="text-align: left;">接入身份标识</td>
</tr>
<tr>
<td style="text-align: left;">shipper_code</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;">是</td>
<td style="text-align: left;">注册公司标识</td>
</tr>
<tr>
<td style="text-align: left;">sign</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;">是</td>
<td style="text-align: left;">API参数签名结果,签名算法参照后续介绍</td>
</tr>
<tr>
<td style="text-align: left;">timestamp</td>
<td style="text-align: left;">String</td>
<td style="text-align: left;">是</td>
<td style="text-align: left;">客户系统发起请求的时间戳(单位毫秒),例 1467883065579。</td>
</tr>
</tbody>
</table>
<h4>业务参数</h4>
<hr />
<p>API调用除了必须包含公共参数外,如果API本身有业务级的参数也必须传入,每个API的业务级参数请考API文档说明。</p>
<h4>调用流程</h4>
<hr />
<p>1、生成签名摘要。参与生成签名摘要的参数有 <strong> shipper_code, access_key, timestamp,业务参数</strong>。
2、加密。 需要加密的参数有 <strong>shipper_code,业务参数</strong>。 </p>
<h4>签名算法</h4>
<hr />
<p>为了防止API调用过程中被黑客恶意篡改,调用任何一个API都需要携带签名,签名大体过程如下:</p>
<ol>
<li>
<p>对所有API请求参数(包括公共参数和业务参数,不包括<strong>sign</strong>参数),根据参数名称的<strong>ASCII</strong>码表的倒序排序。如:foo=1, bar=2, foo_bar=3, foobar=4排序后的顺序是foobar=4,foo_bar=3, foo=1, bar=2</p>
</li>
<li>
<p>将排序好的参数名和参数值拼装在一起,根据上面的示例得到的结果为: foobar4foo_bar3foo1bar2</p>
</li>
<li>
<p>拼接好的字符串必须采用 <strong>UTF-8</strong> 编码,并在其前后拼接 secret 密钥后,再进行信息摘要。信息摘要使用MD5算法。
如: <code>MD5(secret + foobar4foo_bar3foo1bar2 + secret )</code></p>
</li>
<li>将摘要得到的字节流结果以16进制表示。MD5使用128位长度算法,使用16进制表示后,签名的固定长度为32个16进制字符。</li>
</ol>
<h4>代码示例</h4>
<hr />
<h5>JAVA :</h5>
<pre><code class="language-java"> // 第一步:参数逆序处理
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys, Collections.reverseOrder());
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
query.append(secret);// 前后拼接密钥
for (String key : keys) {
String value = params.get(key);
if (StringUtils.areNotEmpty(key, value)){
query.append(key).append(value);
}
}
query.append(secret);// 前后拼接密钥
// 第三步:使用MD5加密 commons-codec库
byte[] bytes = Md5Crypt.md5Crypt(query.toString().getBytes(&quot;UTF-8&quot;));
// 第四步:把二进制转化为大写的十六进制字符
String sign = Hex.encodeHexString(bytes).toUpperCase();
</code></pre>
<h4>调用示例</h4>
<hr />
<p>具体步骤如下:</p>
<h5>1. 准备参数值</h5>
<p>公共参数:</p>
<ul>
<li>access_key = "gsh56123456"</li>
<li>shipper_code = "hjabc"</li>
<li>timestamp = "1467883065579"</li>
</ul>
<h5>2. ASCII 逆序排列</h5>
<ul>
<li>timestamp = "1467883065579"</li>
<li>
<p>shipper_code = "hjabc"</p>
</li>
<li>access_key = "gsh56123456"</li>
</ul>
<h5>3. 参数拼接</h5>
<ul>
<li>拼接结果:timestamp1467883065579shipper_codehjabcplate粤A11111noGSH201703011232amount2500access_keygsh56123456</li>
</ul>
<h5>4. 生成签名</h5>
<ul>
<li>
<pre><code class="language-java">String sign = HEX(MD5( secret + &quot;timestamp1467883065579shipper_codehjabcplate粤A11111noGSH201703011232amount2500access_keygsh56123456&quot; + secret ))</code></pre>
</li>
<li>最终签名值为 66987CB115214E59E6EC978214934FB8</li>
</ul>
<h5>5. shipper_code和业务参数加密</h5>
<ul>
<li>注:access_key, timestamp, sign 不要加密</li>
<li>采用AES加密标准</li>
<li>AES用户密钥由平台生成发放给客户</li>
<li>
<pre><code class="language-java">// 用户密钥
String secret = &quot;mUPNIDoUbsXcQF9Qtm3UnA==&quot;;
// 业务参数JSON串
String json = &quot;{no:'GSH201703011232',plate:'粤A11111',amount:'2500'}&quot;;
String shipper_code = &quot;hjabc&quot;;
// AES加密,得到业务密文 javax.crypto库
String ciphertext1 = AES.encypt(json,secret);
String ciphertext2 = AES.encypt(shipper_code,secret); </code></pre>
</li>
</ul>
<h5>5. 发起HTTP请求</h5>
<p>所有参数和值使用UTF-8编码后,通过POST发送请求
http传,放到body键值对拼接的形式</p>