不要急,源代码分享在最底部,先问你们一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,咱们经过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题,例如:html
- 请求来源(身份)是否合法?
- 请求参数被篡改?
- 请求的惟一性(不可复制)
为了保证数据在通讯时的安全性,咱们能够采用参数签名的方式来进行相关验证。git
案列分析算法
咱们经过给某 [移动端(app)] 写 [后台接口(api)] 的案例进行分析: api
客户端: 如下简称app 安全
后台接口:如下简称api服务器
咱们经过app查询产品列表这个操做来进行分析:app
app中点击查询按钮==》调用api进行查询==》返回查询结果==>显示在app中post
上代码啦 -_-!优化
1、不进行验证的方式加密
api查询接口:
app调用:http://api.test.com/getproducts?参数1=value1.......
如上,这种方式简单粗暴,经过调用getproducts方法便可获取产品列表信息了,可是 这样的方式会存在很严重的安全性问题,没有进行任何的验证,你们均可以经过这个方法获取到产品列表,致使产品信息泄露。
那么,如何验证调用者身份呢?如何防止参数被篡改呢?
2、MD5参数签名的方式
咱们对api查询产品接口进行优化:
1.给app分配对应的key、secret
2.Sign签名,调用API 时须要对请求参数进行签名验证,签名方式以下:
a. 按照请求参数名称将全部请求参数按照字母前后顺序排序获得:keyvaluekeyvalue...keyvalue 字符串如:将arong=1,mrong=2,crong=3 排序为:arong=1, crong=3,mrong=2 而后将参数名和参数值进行拼接获得参数字符串:arong1crong3mrong2。
b. 将secret加在参数字符串的头部后进行MD5加密 ,加密后的字符串需大写。即获得签名Sign
新api接口代码:
app调用:http://api.test.com/getproducts?key=app_key&sign=BCC7C71CF93F9CDBDB88671B701D8A35&参数1=value1&参数2=value2.......
注:secret 仅做加密使用, 为了保证数据安全请不要在请求参数中使用。
如上,优化后的请求多了key和sign参数,这样请求的时候就须要合法的key和正确签名sign才能够获取产品数据。这样就解决了身份验证和防止参数篡改问题,若是请求参数被人拿走,没事,他们永远也拿不到secret,由于secret是不传递的。再也没法伪造合法的请求。
可是...这样就够了吗?细心的同窗可能会发现,若是我获取了你完整的连接,一直使用你的key和sign和同样的参数不就能够正常获取数据了...-_-!是的,仅仅是如上的优化是不够的
请求的惟一性:
为了防止别人重复使用请求参数问题,咱们须要保证请求的惟一性,就是对应请求只能使用一次,这样就算别人拿走了请求的完整连接也是无效的。
惟一性的实现:在如上的请求参数中,咱们加入时间戳 :timestamp(yyyyMMddHHmmss),一样,时间戳做为请求参数之一,也加入sign算法中进行加密。
新的api接口:
app调用:
http://api.test.com/getproducts?key=app_key&sign=BCC7C71CF93F9CDBDB88671B701D8A35×tamp=201603261407&参数1=value1&参数2=value2.......
如上,咱们经过timestamp时间戳用来验证请求是否过时。这样就算被人拿走完整的请求连接也是无效的。
Sign签名安全性分析:
经过上面的案例,咱们能够看出,安全的关键在于参与签名的secret,整个过程当中secret是不参与通讯的,因此只要保证secret不泄露,请求就不会被伪造。
总结
上述的Sign签名的方式可以在必定程度上防止信息被篡改和伪造,保障通讯的安全,这里使用的是MD5进行加密,固然实际使用中你们能够根据实际需求进行自定义签名算法,好比:RSA,SHA等。
源码下载:
源代码:http://git.oschina.net/daimali/Daimali.ISV