2、签名规范
<h2>2.1 签名算法</h2>
<p>签名算法目前只支持 <strong>RSA(SHA256)</strong>,对请求数据统一签名。</p>
<p>在RSA的签名时,需要私钥和公钥一起参与签名。私钥与公钥皆是客户通过<a href="https://docs.open.alipay.com/291/106130">OPENSSL工具</a>(或使用<a href="https://docs.open.alipay.com/291/105971/">支付宝RSA密钥工具</a>)来生成得出的(<strong>注意:生成密钥时JAVA应选择PKCS8格式,其他语言选择PKCS1模式,长度为2048</strong>)。</p>
<p>开发者将生成出的RSA公钥(Public Key)提供给wb平台技术支持人员进行配置,同时也将PayCloud平台的公钥(PayCloud Public Key)设置在商户系统中。当商户系统请求报文签名,或响应报文验证签名时,需要用到自己的私钥及PayCloud平台的公钥。</p>
<h2>2.2 生成待签名字符串</h2>
<h4>第一步: 确立待签名参数</h4>
<p>在客户请求参数列表中和PayCloud平台返回参数列表和异步通知参数列表中,对所有API请求参数(包括公共请求/响应参数和业务请求/响应参数,但除去sign参数及值为NULL或空字符串的参数)。
**
图片等文件需要将文件内容进行MD5,并转换为16位长度的十六进制小写字符串,作为待参加签名参数。</p>
<blockquote>
<p><em><strong>注意</strong></em><strong>:</strong>根据HTTP协议要求,传递参数的值中如果存在特殊字符(如:&、@等),那么该值需要做URL Encoding,这样请求接收方才能接收到正确的参数值。这种情况下,待签名数据应该是原生值而不是encoding之后的值。例如:调用某接口需要对请求参数email进行数字签名,那么待签名数据应该是email=test@msn.com,而不是email=test%40msn.com。</p>
</blockquote>
<p>例如下面的参数数组:</p>
<pre><code class="language-java">String[] parameters={
"app_id=wxd16bdc77aa30ce7e",
"method=pay.orderquery",
"provider_id=2088101568338364",
"format=JSON",
"charset=UTF-8",
"sign_type=RSA",
"version=1.0",
"timestamp=2018-10-30 14:19:23",
"merchant_no=100001876",
"out_trade_no=TB20181030000875",
"ab_no="
};</code></pre>
<p>处理后需要参与签名的参数为(_根据规则,sign_type和ab_no不参与签名,__sign_type固定不参与签名,__ab<em>no值为空不参与签名</em>)</p>
<pre><code class="language-java">String[] parameters={
"app_id=wxd16bdc77aa30ce7e",
"method=pay.orderquery",
"provider_id=2088101568338364",
"format=JSON",
"charset=UTF-8",
"version=1.0",
"timestamp=2018-10-30 14:19:23",
"merchant_no=100001876",
"out_trade_no=TB20181030000875"
};</code></pre>
<h4>第二步:参数排序</h4>
<p>参数名ASCII码从小到大排序(从a到z的顺序排序,若遇到相同首字母,则看第二个字母,以此类推)。
第一步排序后的数组为:</p>
<pre><code class="language-java">String[] parameters={
"app_id=wxd16bdc77aa30ce7e",
"charset=UTF-8",
"format=JSON",
"merchant_no=100001876",
"method=pay.orderquery",
"out_trade_no=TB20181030000875",
"provider_id=2088101568338364",
"timestamp=2018-10-30 14:19:23",
"version=1.0"
};</code></pre>
<h4>第三步: 参数拼接</h4>
<p>使用“&”字符连接已排序的参数,上一步示例连接后的字符串为:</p>
<pre><code>app_id=wxd16bdc77aa30ce7e&charset=UTF-8&format=JSON&merchant_no=100001876&method=pay.orderquery&out_trade_no=TB20181030000875&provider_id=2088101568338364&timestamp=2018-10-3014:19:23&version=1.0</code></pre>
<h2>2.3 签名</h2>
<h4>RSA签名</h4>
<ul>
<li><strong>请求时签名</strong></li>
</ul>
<p>当拿到请求时的待签名字符串后,把待签名字符串与客户的私钥一同放入RSA的签名函数中进行签名运算(SHA256WithRSA签名运算并进行Base64编码),从而得到签名结果字符串。</p>
<ul>
<li><strong>异步通知/同步返回时验证签名</strong></li>
</ul>
<p>当获得通知或同步返回时的待签名字符串后,把待签名字符串、PayCloud平台提供的公钥、通知或同步返回参数中的参数sign的值三者一同放入RSA的签名函数中进行非对称的签名运算(SHA256WithRSA签名运算并进行Base64编码),来判断签名是否验证通过。</p>