https://zhuanlan.zhihu.com/p/21306631

移动API设计与安全存储

晚安周先生
2 年前
最近在重新排查API的时候,我们在企业内部突然讨论到一个问题。我们的APP接口安全吗?一个安全的API接口是该如何设计的?当然,对我看来我们的目前提供给APP使用的API并不安全,自己之前都是在关注逆向与hook也没有思考过类似的问题,如何设计一个安全的API估计很多朋友都遇到过此问题。今天这里总结一下我们内部讨论的结果:

为什么安全性更高的https并没有普及?
说到让我们目前的接口更为的安全,很多朋友第一时间就想到的是将http协议换为https协议哈。我们可以看看所有大型网站,例如京东,淘宝,支付宝,涉及到登录和支付的页面,url都是以https开头,这就意味着,这次通讯是使用https。开放平台的api,例如新浪微博,腾讯等,api请求都是以https开头的。https是业界常用的保证安全性的协议。问题来了,为什么https比http好,在如今网络发展的现在并没有完全普及?

效率低?
涉及安全问题的api,都应该使用https协议。虽然,https为了保证安全性,在效率上是比http协议低。

价格昂贵?

通常来说我们自签名的证书已经能够满足我们的日常需求了,如果不放心ssl服务的供应商有很多,当然国内最有名的就是wosign了,(也许你要问为什么要买国内的, 国内的安全性并没有Symantec高,其实就是因为可以开发票),我们具体查看他们的价格,发现都是在5000~10000不等,其实还算便宜。

https一定安全吗?
这个问题才是我们最关心的问题,首先我们重新理解一下什么是https,不明白的可以先看看我之前的文章:聊聊HTTPS与Android安全。

SSL/TLS协议本身就存在很多漏洞,如SSL 2.0中主要存在的问题如下:
MAC不能覆盖填充长度域,攻击者可能利用这点破坏消息完整性;
缺乏握手认证,攻击者可以篡改密码套件列表,诱骗通信双方使用较弱的密码套件;
使用较弱的或有问题的密码算法(如MD5,RC4等),或者使用不安全的分组模式(如CBC模式);
对于不同的密码学基元使用相同的密钥,违背基本安全常识。

当然,更多的APP是因为对安全常识理解不到位,对信任的证书没有做到排除与过滤,不检查服务器是否可信、过期、CA合法。这样的情况下贸然使用https协议,加上的这层安全也是形同虚设。

竞品的接口设计如何?
如何设计自己的API接口我们同样可以先看看竞品的设计情况,结合来看。抓取了几家竞品获取用户信息的接口

竞品一:

GET http://XXXX.cn/appinterface/App2?a=getUserInfo&loginToken=b5f5b36237e9da4ca2c6a381634407d3&uuid=acc78901-a013-40c9-84a3-c39e42c85af4&faId=69164 HTTP/1.1
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI NOTE LTE MIUI/5.12.17)
Host: XXXX.cn
Connection: Keep-Alive
Accept-Encoding: gzip
完全遵循REST协议,这个api接口通过url参数附带着

参数说明a具体的action接口名称token用户登录后生成的tokenuuid设备的唯一标识faIduserid
竞品二:

POST https://XXXXX.com/api/User/GetUserBaseInfoDetail HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI NOTE LTE MIUI/5.12.17)
Host: XXXXX.com
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 210

{“sign”:”4E1DEA3C690E6E722DE5DA002006F809”,”apiVersion”:”1.0.0.0”,”timeStamp”:”2016-06-05 21:02:54”,”userId”:100078,”userMobile”:”18310267036”,”channel”:2,”version”:”2.5.1”,”appKey”:”ycfandroidkzl18d7zdpakfcr”}
逆向APP获取数据

竞品二所有接口都采用了POST请求,
直接就是采用了自签名的的https协议作为app api接口,问题也就是在于它们太依赖与https协议,完全没有理解https就贸然使用,没有做好任何的保护措施。相当于裸奔。
参数说明sign逆向app发现,sign = MD5(所有参数 + salt)apiVersion协议的版本号timeStamp时间戳userId用户iduserMobile用户的手机号channel渠道号versionapp版本号appKey加密的salt (⊙﹏⊙)b 居然这么传
当然,这个api接口设计的安全性也显而易见,我们不做过多分析。

竞品三:

GET http://XXXXX.com/app/userIdentity/GetUserNickinfo?uid=869821725&sign=e5e1692a7f6d6e99aef1af367c7689d2&sid=f611ca17c3733c772333b791e6f9c113&platform=3&device_version=4.4.4&peerid=865982027912248&device=MI+NOTE+LTE&cid=m5YT2kTfnwo.&version=3.2 HTTP/1.1
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI NOTE LTE MIUI/5.12.17)
Host: XXXXX.com
Connection: Keep-Alive
Accept-Encoding: gzip
参数说明uiduseridsign所有参数的md5,与竞品二类似sidsession id 登录超时判断platform平台device_version设备版本号peerid一个特殊处理后的时间戳device设备名称cid客户端标识,一个写死的值version协议的版本号
如何设计更为安全的API?
看到上面的几家竞品公司的协议,有好有坏,但是同样值得我们的借鉴,我们可以使用Https协议替代我们原有的协议,但是,一些安全的设计与存储的工作同样必不可少。

以目前最为流行的RESTFull协议作为案例,REST的全称是REpresentational State Transfer,表示表述性无状态传输,无需session,所以每次请求都得带上身份认证信息。rest是基于http协议的,也是无状态的。只是一种架构方式,所以它的安全特性都需我们自己实现,没有现成的。

请求身份验证
在HTTP协议之上处理授权有很多方法,如HTTP BASIC Auth,OAuth,HMAC Auth等,其核心思想都是验证某个请求是由一个合法的请求者发起。

Basic Auth
Basic Auth简单点说明就是每次请求API时都提供用户的username和password,这种方式优点和缺点都很明显。如下所示:
GET /private/index.html HTTP/1.0Host: localhostAuthorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
其中的username与password我们可以做一些加密处理(如上面就使用了Base64处理当然可以使用更为复杂的),但是由于每次都传输了重要的数据,违背了最小暴露原则,隐患巨大。

HMAC Auth
每个客户端第一次发出请求时,将自己的唯一HASH MAC 和请求包发给服务器,以后,服务器就依据这个HMAC来判断客户端的唯一性。优劣与Basic Auth类似。

OAuth
由于Basic Auth每次都暴露了重要的数据,那么OAuth的目的就是将此隐患去掉,OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的。我们所说的OAuth都是只OAuth2.0。

用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。
授权成功后,服务提供方引导用户返回客户端的网页。
客户端根据临时令牌从服务提供方那里获取访问令牌。
服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。
客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。
OAuth是个安全相关的协议,作用在于,使用户授权第三方的应用程序访问用户的web资源,并且不需要向第三方应用程序透露自己的密码。毫无疑问,OAuth对目前来说是一个不错的解决方案,如今微信、qq、百度等第三方授权协议都是基于此,同时OAuth的劣处也同样是在它的思想上,需要资源服务器与授权服务器相互配置,使用与开发上都较为复杂。

授权过滤
既然做到了身份认证,我们就可以对不同来源的token做一个角色划分。常见的如Admin(管理员)、Customer(顾客)。我们简单的书写一个demo,如下所示:

if(isCustom) {
if(Pattern.compile(“^(/admin).*”).matcher(url).matches()) {
return false;
}
}
对于不同角色的用户,开放不同的api接口。

敏感id设计
如以自增长的数据库主键id作为接口协议的唯一查询。

GET http://XXXXX.com/api/User/123
一旦,协议出现问题,极容易被扫库,导致所有的User表中信息暴露。可以自定义一些自己适当的生成唯一id的作为,参考优酷重写url并生成唯一视频id的做法

http://v.youku.com/v_show/id_XMTU5NzA5MDY4NA==.html
操作频率限制
敏感操作必须限制用户操作的频率,可以的话对每分钟操作的次数、每天操作的次数、每个月操作的次数都做限制,防止而已撞库与暴力破解。

if (System.currentTimeMillis() / 1000 - countLimit.getMinuteTime() > 60) {
countLimit.setMinuteCount(1);
countLimit.setMinuteTime(System.currentTimeMillis() / 1000);
isLimit = false;
} else {
if (countLimit.getMinuteCount() >= LOGIN_MIN_COUNT) {
isLimit = true;
} else {
countLimit.setMinuteCount(countLimit.getMinuteCount() + 1);
countLimit.setMinuteTime(System.currentTimeMillis() / 1000);
isLimit = false;
}
}
数据格式校验
对于每一个请求过来的参数确保过来的参数合法性,如下是一个简单的测试请求

http://XXX.com/getFile?path=../../../server.config
我们可以对我们需要处理的数据做一个合法性验证,如是否是正整数,是否以../开头等等。

当然,如果使用的是xml协议,还需要注意下xml注入的问题。

APP加密存储
这个是一个复杂的问题,今天写的太多了,改天再向大家介绍。对于普通的企业来说,如果弄不明白,推荐大家直接使用360加固就好。

ps:好久没有更新博客了,创业这段时间比较忙,这次真的是在大半夜把本篇博客完成。移动API设计上的安全问题远不止于我们想到的这点,本人能想到的也不多,都是大家思维碰撞出来的结果。我们公司比较Open经常会举办一些技术上的考虑与学习会议,有兴趣的朋友可以加一下我的微信,欢迎大家和我交流,欢迎来我公司一些分享技术心得。

移动API设计与安全存储相关推荐

  1. java开发checklist,Java API设计CheckList

    API设计原则:正确.好名.易用.易学.够快.够小.但我们从来不缺原则,〜〜〜 Interface 1.The Importance of Being Use Case Oriented,一个接口应当 ...

  2. Nacos 1.0.0 GA,架构、功能与 API 设计全面重构

    Nacos 1.0.0 GA 版本发布了,此版本在架构.功能和 API 设计上进行了全方位的重构和升级. 此版本新特性包括: 注册实例支持 ephemeral 字段 Nacos 1.0.0 版本在 i ...

  3. 有点长的 Java API 设计清单

    在设计Java API的时候总是有很多不同的规范和考量.与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度.就像飞行员起飞前的检查清单,这张清单将帮助软件设计者在设计Java API的过程 ...

  4. 阿里研究员谷朴:API 设计最佳实践的思考

    2019独角兽企业重金招聘Python工程师标准>>> API是软件系统的核心,而软件系统的复杂度Complexity是大规模软件系统能否成功最重要的因素.但复杂度Complexit ...

  5. 深度 | API 设计最佳实践的思考

    API 是模块或者子系统之间交互的接口定义.好的系统架构离不开好的 API 设计,而一个设计不够完善的 API 则注定会导致系统的后续发展和维护非常困难. 接下来,阿里巴巴研究员谷朴将给出建议,什么样 ...

  6. Java API 设计清单

    为什么80%的码农都做不了架构师?>>>    在设计Java API的时候总是有很多不同的规范和考量.与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度.就像飞行员起飞 ...

  7. Apache Beam的API设计

    Apache Beam的API设计 Apache Beam还在开发之中,后续对应的API设计可能会有所变化,不过从当前版本来看,基于对数据处理领域对象的抽象,API的设计风格大量使用泛型来定义,具有很 ...

  8. AOL架构原则.优秀API设计.Yeoman工具

    本期的架构周报主要关注AOL(美国在线)的高可用性架构.技术专家Joshua Bloch对优秀API的设计观点.新的Web应用开发工具集Yeoman和OpenStack网络项目Neutron的介绍. ...

  9. C++ API设计笔记

    <C++ API设计>原英文版由Martin Reddy著,中文版出版于2013年,这里是中文版的笔记. 1. API简介 1.1 什么是API:API(Application Progr ...

  10. Dingo + Laravel + JWT + Entrust + memcache 实现API设计

    Dingo + Laravel + JWT + Entrust + memcache 实现API设计 Dingo Api 是一个为laravel设计的用于API开发的开源包,规范和简化了Api的设计 ...

最新文章

  1. 科技|全球首款飞行汽车开始量产!下月开始预售,2023年后或可实现一键打“飞车”...
  2. 【转】Android 快捷方式的创建
  3. IntelliJ IDEA部署tomcat时Edit Configuration无artifact选项
  4. 全国首个人工智能专业,怎么学?
  5. Python核心场景自动化测试项目实战(二)
  6. es6 对象的扩展运算符
  7. Red Hat日志文件系统-ext3
  8. eclipse下开发简单的Java Web Service
  9. SQL ALTER TABLE 语句在项目中的使用
  10. log4j日志级别以及配置
  11. React:Redux简介
  12. 解决VM虚拟机鼠标闪烁的问题
  13. Python一元二次方程求根
  14. 2021年Java基础面试题总结
  15. 服务器怎么做无限耐久装备,饥荒物品无限耐久控制台指令 | 手游网游页游攻略大全...
  16. iOS 1 到 iOS 10 ,我都快老了
  17. QT中主线程终止子线程中的死循环
  18. 直播技术——视频编解码(理论基础)
  19. 深圳软件测试几月份好找工作,上海与深圳的软件测试发展,未来哪个更有发展前景?...
  20. CPU/GPU/GPGPU简介

热门文章

  1. 透析JMS、MQ看看应用与应用的底层如何完成通信
  2. SHELL 002 -- ps命令常用方法
  3. SDN驱动云数据中心的发展
  4. MySQL – iBatis – 文件存储
  5. 60佳优秀的国外电子商务网站设计案例(上篇)
  6. spring-第十八篇之spring AOP基于XML配置文件的管理方式
  7. 摩天大楼建造大跃进折射啥危机?
  8. 顺序输出一个整数的各位数字
  9. wpf Content数据绑定StringFormat起作用的原理和解决(转)
  10. 高级程序员不写代码?