什么是 Open API
把部分对外服务的功能封装成一系列API并供对方或第三方使用,这种API就叫做Open API。可是随着接口的暴露,数据安全性就显得尤为重要了。Open API的签名就是为了保证数据安全性而产生的。
Open API需要解决以下3个问题
请求是否合法:是否是我规定的那个人
请求是否被篡改:是否被第三方劫持并篡改参数
防止重复请求(防重放):是否重复请求
签名生成规则
核心元素:
appKey
appSecert
预定义的加密方式
timestamp,nonce
appKey 是为了保证该调用请求是平台授权过的调用方发出的,保证请求方唯一性,
appSecert 是组成签名的一部分,增加暴力解密的难度的,通常是一段密文,如 SECERT_A;
预定义加密方式是双方约定好的加密方式,一般为散列非可逆加密,如 MD5、SHA1;
规则实例
将 APPKey 加入值请求参数
www.sample.com/openapi/getmessage?appKey=test01&name=spiderman&movie=Spider-Man:Homecoming
将每个请求参数去除“=”,按ASCII升序按“参数1参数值1参数2参数值2……”的格式组成特定的字符串
appKeytest01movieSpiderManHomecomingnamespiderman
将秘钥SECERT_A加入上述字符串的前后成为
SECERT_AappKeytest01movieSpiderManHomecomingnamespidermanSECERT_A
按约定方式(如 SHA1)加密
2995c83bbc12b147c9b5645396e5700e6af92b7f
拼接所有参数,组成API请求
第4步生成的字符串,就是我们的签名sign,也作为一个查询参数加入到我们的请求中那么请求就变成了
www.sample.com/openapi/getmessage?name=spiderman&movie=Spider-Man:Homecoming&sign=2995c83bbc12b147c9b5645396e5700e6af92b7f
平台服务器在接到这个请求之后,会将请求包中的所有参数按以上相同的方式进行加密。如果生成的参数签名一致,则签名通过,请求的合法性和请求参数都得到保护,不会被第三方劫持后篡改变为它用。
如果仿冒者监听并截取到了请求片段,然后把签名单独截取出来模仿正式请求方欺骗服务器进行重复请求,这也会造成安全问题,这攻击方式就叫重放攻击(replay 攻击)。
可以通过加入 timestamp+nonce 两个参数来控制请求有效性,防止重放攻击。
请求端:timestamp由请求方生成,代表请求被发送的时间(需双方共用一套时间计数系统)随请求参数一并发出,并将 timestamp作为一个参数加入 sign 加密计算。
服务端:平台服务器接到请求后对比当前时间戳,设定不超过30s 即认为该请求正常,否则认为超时并不反馈结果(由于实际传输时间差的存在所以不可能无限缩小超时时间)。
仿冒者仍然有30秒的时间来模仿请求进行重放攻击。所以更进一步地,可以为sign 加上一个随机码(称之为盐值)这里我们定义为 nonce。
请求端:nonce 是由请求方生成的随机数(在规定的时间内保证有充足的随机数产生,即在30s 内产生的随机数重复的概率为0)也作为参数之一加入 sign 签名。
服务端:服务器接受到请求先判定 nonce 是否被请求过,如果发现 nonce 参数在规定时间是全新的则正常返回结果,反之,则判定是重放攻击。而由于以上2个参数也写入了签名当中,攻击方刻意增加或伪造 timestamp 和 nonce 企图逃过重放判定都会导致签名不通过而失败。
综上所述,接口签名认证的安全性,最终取决于 appSecert密钥是否有被泄露。
--非原创,纯属知识搬运。