最近这些天在帮客户对接一个游戏平台的接口(用PHP实现),拉到一个WX群一起探讨。对方给了份DOC文档,我打开一看,有各种接口的调用和传参说明,代码示例是用C#写的,我问了对方的技术人员,有没有PHPdemo参考。直接来了一句没有,那时候我预感将要填坑。
头一次我遇到一个也算很大的平台提供接口给合作方使用,居然没有常见编程语言的demo示例,首先体验上就不是很好。
通常在接口开发上,涉及到敏感接口要加各种验证。比如,加密和签名。在这一次开发商,统统都用上了。
加密采用的是对称加密,就是由接口提供方分配给我一对类似于APPID和APPKEY的东西,最后来多一个初始向量,用于加密初始化。
为了防止数据被篡改,需要对传输过来的请求数据按一定的规则取摘要,这边是MD5摘要。
比较重要的一点就是当中APPKEY充当两个角色的身份,一个是对称加密的秘钥,一个是参与MD5摘要计算。
在对接过程中,一开始是出现签名失败,我反复检查数据无误,于接口方共同排查之后,他们那边最终给出的反馈是,参与对称加密的APPKEY只需要截取部分字符串。。。。。然而文档中没有提及到这一块,这种行为有点太过于小心过头。
如果真是很担心被人猜测出算法,那应该尽可能对所有数据加密,部分请求接口数据居然不加密。这一块也是规范没有确立好。
一般往接口发送请求要注册回调通知,用于异步处理数据,内容也不需要解密,只需要签名校验。然后问题恰恰处在签名校验上。请求跟回调的签名算法貌似一样,但是居然有细微之处,就是回调通知的数据是经过URL编码的,额外加多一些字段参与校验,也没有在接口文档中提及,这种不友好的接口提供方行为真让人方案,最坑爹的属于一个编程语言上的细节问题。
PHP调用md5函数签名后返回的32位字符串是小写的。而C#是大写的,这还不是致命的,我们知道为了方便数据在网络上传输,我们通常需要对数据做URL编码,把当中的左右花括号、双引号、冒号、逗号做转义。两种编程语言都能实现,然后经过PHP的编码相关字符串会是大写,而C#是小写,如果不注意这两点,进行签名校验将会出问题。
为了兼容,我在PHP上做了替换,代码如下。
$new_str = urlencode($JsonData);
$new_str = str_replace(
['%7B', '%3A', '%2C', '%7D'],
['%7b', '%3a', '%2c', '%7d'],
$new_str
);
$new_str= 'JsonData='. $new_str;
$mySign = $this->sign($new_str);
if (strtoupper($mySign)!=$Sign) {
Json(['status' => 0, 'msg' => '签名错误','sign'=>$Sign, 'mySign'=> $mySign]);
}
其中的编码字符替换如下
%7B {
%22 "
%3A :
%2C ,
%7D }
在后来的实践中发现这个方式也不妥,既然是接口方提供的接口给合作方使用的,尽可能做到跨平台统一,这样才易于维护。如果我一味迁就他,后期改接口我这边还是得修改。而且上面这些情况不适用于返回中文字符的情况,因为中文字符编码也会转成编码字符。这个时候替换的东西就多了去了。因此最好的方式还是让接口方转换成小写的字符传输过来