对APIv3强制验签逻辑进行优化,对已知无签返回的请求,自动忽略验签
TheNorthMemory opened this issue · comments
运行环境
- wechatpay-php: 1.4.4
描述你的问题现象
需求
引申自 #92 , 当前已知在 APIv3
的三个接口上,有三种“特殊”逻辑,当前版本SDK并没有特殊处理,如下:
1. 国内商户客诉图片下载
URL: /v3/merchant-service/images/{slot}
接口本身返回的流stream,无验签逻辑;
2. 国内商户账单下载
URL: /v3/billdownload/file
接口本身返回的流stream,验签逻辑依赖前置请求账单的SHA1
摘要,而前置接口的返回的SHA1
值,已按标准RSA公钥逻辑验签;
3. 海外商户账单下载
URL: /hk/v3/statements
请求的返回值,签名含两种逻辑,标准RSA公钥验签逻辑注1及流stream SHA1
摘要逻辑;
注1: 验签的是 SHA1
摘要的JSON
表达式,而非流,与标准RSA公钥验签验证返回BODY
不同;
分析
-
第1种情形,接口设计的比较另类另说(见 #85 ),无验签逻辑需要客户端自动忽略;
-
第2种是两步
请求
分开验签,先RSA
后SHA1
,验签逻辑含上下文context
语境,后置的客户端本地验签逻辑可循 以函数链的形式流式下载交易帐单 示例,在->then
链上处理,当前请求返回值无明确签名,客户端需要忽略验签; -
第3种情形可以看作是第2种的特例,一步请求,接口即回吐了
RSA
签名又包含SHA1
摘要,客户端设计可以仿第2种逻辑,仅对RSA签名部分进行验签,保证当前请求的返回值,是来自平台RSA
私钥数据签名注2,SHA1
摘要逻辑交由客户端本地在->then
链上自行比对摘要值;
注2: 按照规范,非对称加密的公钥是公开的,可任意发行的,而平台RSA私钥
是私密数据,一次请求即含签名又含摘要,虽然任何人(持有效公钥)都可以验签,但RSA签名值
本身是不可伪造,是安全的。
改进
按照上述分析,对前两种接口设计,当次请求/响应需要忽略RSA验签
;对第三种逻辑,需要构造一个本地摘要值JSON
串,做一次RSA公钥验签
,验签若失败,则按当前处理逻辑抛\GuzzleHttp\Exception\RequestException
异常;RSA验签
成功则(忽略SHA1
值比对逻辑)放行。