API server之签名验证设计

  • 2016-01-22
  • 1530
  • 89

之前接到一个项目,抛开业务层,单从技术层扼要的说便是开发基于REST风格的API服务,采用http的方式实现协议通信,使用post方式提交,post和get方式查询。请求的URL格式:http://www.xxx.com/interface.json?sign=sign_value&p2=v2&p1=v1&p3=&pn=vn

基于安全性考虑,于是设计时参照了百度和淘宝的api——第三方通知过来的参数里有sign(签名),接口必须对sign进行验证,只有sign正确的请求才能进行处理,sign验证会用到通知验证密钥。

具体规则如下:

首先,将通知过来的所有参数(注意是所有参数),除去sign本身,以及值是空的参数,按参数名字母升序排序,然后按参数1值1参数2值2…参数n值n(这里的参数和值必须是原始值,不能是经过处理的)的方式进行连接,得到一个字符串然后在连接后得到的字符串后面加上私钥,然后计算md5值,转成大写最后拿这个计算出来的MD5串同第三方通知里面的sign参数值做比较,如果一致,表明该通知是安全的(是第三方发的且没有被篡改过);否则,该通知可能是被篡改过的,存在不安全性例如,假设第三方平台某些通知过来的数据是:http://www.xxx.com/interface.json?sign=sign_value&p2=v2&p1=v1&p3=&pn=vn

(实际情况是通过post请求发送通知的)。其中sign参数对应的sign_value就是签名的值,需要用来和根据其他参数计算出来的签名值做对比,看是否一致。

具体算法步骤如下:

Step1:拼接字符串,首先去除sign参数本身,然后去除值是空的参数p3,剩下p2=v2&p1=v1&pn=vn,然后按参数名字符升序排序, p1=v1&p2=v2&pn=vn,然后做参数名和值的拼接,最后得到p1v1p2v2pnvn。

Step2:在上面拼接得到的字符串后面加上通知验证密钥,我们假设是abc,得到新的字符串p1v1p2v2pnvnabc,然后将这个字符串进行md5计算,假设得到的是abcdef,然后转为大写,得到ABCDEF这个签名值,注意,计算md5之前请确保字符串是utf8编码的,如果是其他编码,那么计算出来的签名会校验失败

Step3:将上面计算得到的ABCDEF这个签名值和参数中通知过来的sign对应的参数值进行对比,如果是一致的,那么就校验通过,如果不一致,说明参数被修改过,不进行处理。

 

PHP示例代码:

参考连接:

百度开发者中心之REST API

淘宝api帮助文档

 


上一篇:  下一篇:

评论

还没有任何评论,你来说两句吧

Copyright © 2014-2016 lxlxw All Right Reserved