用产品思维设计API—— 安全,就只能用HTTPS?
Posted 北漂周
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用产品思维设计API—— 安全,就只能用HTTPS?相关的知识,希望对你有一定的参考价值。
用产品思维设计API(五)—— 安全,就只能用HTTPS?
前言
最近公司内部在重构项目代码,包括API方向的重构,期间遇到了很多的问题,不由得让我重新思考了下。
- 一个优雅的API该如何设计?
- 前后端分离之后,API真的解耦分离了吗?
- 不断的版本迭代,API的兼容性该如何做?ps.这里所说的API仅为Web API,提供APP\\WEB开发使用。
年前,我司内部的接口已经进入了一个完全的重构阶段,参考了市面上各大平台的API和文档,自己也总结出了很多的心得。这里向大家分享一下,接下来一个月,我们向从下面几个方面向大家介绍一个优雅的API(至少我认为挺优雅)该如何设计。
- RESTful就是个骗局 (http://blog.csdn.net/yzzst/article/details/53775319)
- 数据解耦,才是前后分离的本质(http://blog.csdn.net/yzzst/article/details/53844590)
- 版本控制,没有你想的这么简单(http://blog.csdn.net/yzzst/article/details/54755077)
- 随意定义错误码,你还在这样干?(http://blog.csdn.net/yzzst/article/details/54799971)
- 安全,就只能用HTTPS?(http://blog.csdn.net/yzzst/article/details/54882346)
ps. 打一个广告,公司内部现在在招聘各种技术岗位,Java、android、前端等,待遇保证能让你涨30%,有兴趣的朋友可以加韬哥的微信(微信号:stchou_zst),二维码在文章最后。
安全是一个老生常谈的问题,在API设计中也备受关注。但是,对于很多人的理解,Web API 的安全就是使用Https协议。世界上没有什么东西是绝对的,这里我们直接给出结论:
安全 ≠ HTTPS
如果还有朋友对于https协议一知半解的话,可以看一下我之前的博文:http://blog.csdn.net/yzzst/article/details/46693685
信息安全三要素
在数据传输中的三要素:
1. 保密性
2. 完整性
3. 可用性
API的安全判断和主要的攻击手段也是从这三个方便延伸出来,常见的有:
- API恶意调用,消耗系统资源(如登录、注册、验证码等等)——(不可用)
- 篡改数据,制造垃圾数据 ——(不可用)
- 使用Root设备,进行Https抓包 ——(不保密)
- 重放(Replay)攻击 ——(不完整)
那么我们设计API的时候,对应的防御手段也由此而来了:
- 对每一个API接口请求进行签名认证,防止使用fiddler等抓包工具轻易的抓包、篡改、提交等等。
- 加入时间戳,做频率时间验证。
- 对一些消耗性资源做频率限制,如:短信验证码下发同一个手机号每分钟仅允许1次
- 对于一些敏感数据再次加密。
API自签名
签名的目的是为了确定我们的API请求是来自于自己的客户端,例如对于下面这个接口而言
http://api.test.com/getOrder?query=中融&pageSize=10
所包含的信息虽然能够然接口正常使用,但信息太少无法保证这个请求来源的唯一性和没有必要的安全性,我们必须针对这个请求加入一个签名字段Sign
构造签名sign?
签名的过程是将请求参数串以及APP密钥根据一定签名算法生成的签名值,作为新的请求参数从而提高访问过程中的防篡改性。即,告诉服务器,你是谁?在什么时间?你想干什么?你的口令?
那么我们现在就定义几个字段表示这些数据:
操作 | 对应字段 | 说明 |
---|---|---|
你是谁? | accessId、accessKey | 每一个版本的客户端接入之前动态分配的,1. 做验证是计算使用。 2. 方便以后启用/停用任意一个api来源 |
在什么时间? | timeStamp | 时间戳 |
你想干什么? | /getOrder?query=中融&pageSize=10 | 之前的原有操作 |
你的口令? | sign | 一个不可逆算法,一般采用sha1或md5, |
我们的Sign签名算法为:
Sign = HMAC_SHA1(accessKey + sourceRequest + timeStamp)
如这里我们已经获取有一个,
accessId=9999
accessKey=ABCDEFG
的Android客户端希望请求接口
/getOrder?query=中融&pageSize=10
Step1:获取当前时间戳
/getOrder?query=中融&pageSize=10&timeStap=1361431471
url编号后得到,请求源数据串(sourceRequst)
%2fgetOrder%3fquery%3d%e4%b8%ad%e8%9e%8d%26pageSize%3d10%26timeStap%3d1361431471
Step2:生成Sign
Sign = HMAC_SHA1(accessKey + sourceRequest + timeStamp)
Sign = 51856f01388a190a42f7fd7f73255240dfca7e97
Step3: 重新生产请求地址
/getOrder?query=中融&pageSize=10&timeStap=1361431471&accessId=9999&sign=51856f01388a190a42f7fd7f73255240dfca7e97
该设计优势
- 可以根据timeStap对接口进行时间限制,如五分钟之内有效,如果修改时间必定会修改sign。
- sign签名可以校验请求数据是否被篡改
- 加入accessId,可以监控每一个api渠道来源的是否正常,动态启用/停用该渠道
- 加密、解密速度快
该设计劣势
- 整个sign的构造过程在客户端完成,对于客户端的防止逆向要求较高
频率限制
对于一些比较重要的资源接口,如:下发短信验证码、发送邮件、下单等,操作会消耗公司内部的系统资源和服务器资源,如果被其他人恶意调用的极有可能造成服务的不可用性,即常说的DDOS。
这个时候我们就必须对一些接口进行操作频率限制。可以按年、月、日、时、分、秒6个维度来做判断。如
接口 | 说明 | 使用频率 |
---|---|---|
downVerfyCode | 下发验证码 | 无登录操作。每个设备id,每分钟1次,每天200次 |
sendEmail | 发送邮件 | 无登录操作。每个设备id,每天50次,每个月200次 |
createOrder | 下单 | 登录后的操作。每个账户,每分钟10次 |
PS. 不同的接口频率判断标准不一样,根据具体的需求进行具体分析,对于没有登录就能够操作的接口,我们只能用设备id(DeviceId)做判断了。
敏感数据再次加密
- 使用SSL协议
- 对于敏感的数据,加入随即盐的方式存储以防范数据被篡改。
如密码不要使用简单的MD5/SHA1,适当的可以
passwordEncrypt = MD5(password + phoneNumber + 'chengyi')
写在后面,刚过完年,公司业务繁忙,重构任务重大,更新博客也慢了。希望大家多多包涵。
@author zhoushengtao(周圣韬)
@since 2017年2月5日 17:54
@weixin stchou_zst
@blog http://blog.csdn.net/yzzst
以上是关于用产品思维设计API—— 安全,就只能用HTTPS?的主要内容,如果未能解决你的问题,请参考以下文章