众所周知,SOAP 是基于XML的webservice协议,传的数据都是xml格式的,而当下resftul设计比较火,因为快效率高,但是安全性就不及SOAP,

SOAP定义了xml-security的一些规范,除了传数据,还要传额外的安全认证信息。而restful设计没有对安全性规范做什么定义。

那么如何确保Restful设计的安全性呢?

其实不管什么SOA协议,都要面临着安全性问题,也就是客户端和服务器端之间的认证问题,这里顺便扯一下SOA,SOA就是对外提供服务接口的一种思想,可以很多技术实现,什么XML-RPC,RMI,SOAP,Restful等等,(当然前面两种用得很少了)

通常认证有几种情形,

1:常用的用户名密码+认证码登录(登录验证)

2:Cookie + Session

原理即当客户端登录完毕之后,给客户端返回一个 cookie ,服务器端控制该 session 的有效期, 每次请求都带上该值,然后服务器端做验证,退出之后,客户端通知服务端端销毁 session ,自身销毁 cookie 。但是如果抓包获取到 cookie ,就能任意伪造请求了。

危险性高,实际开发估计使用得还不少。

3:基于2的问题,对于CSRF攻击,我们通常会额外生成一个token,放在HttpSession里,每次get/post请求都必须带上这个token,前端JSP通过session.getAttribute("token")就能获取到。如果前后端完全分离的话,那先要握一次手,由客户端保存住token。

4: 太小看黑客了,包都能抓到,token也能抓到,所以方法3也然并卵。

于是想一种办法,让黑客即使抓到包也看不懂,yes,就必须对关键信息进行加密。而且加密还得越复杂越好,让黑客逆向不出来。

加密的问题后面再说,参考(http://www.tuicool.com/articles/Zb6j6rR)的一种认证方法很好,

Api Key + Security Key + Sign

这里的认证逻辑即:

  1. 用户登录返回一个 api_key 和 security_key ;

  2. 然后客户端将 security_key 存在客户端;

  3. 当要发送请求之前,通过 function2 加密方法,把如图所示的五个值一起加密,得到一个 sign ;

  4. 发送请求的时候,则将除去 security_key 之外的值,以及 sign 一起发送给服务器端;

  5. 服务器端首先验证时间戳是否有效,比如是服务器时间戳5分钟之前的请求视为无效;

  6. 然后根据 api_key 验证 sercurity_key ;

  7. 最后验证 sign 。

是否需要加上时间戳验证?

上面的认证逻辑中加密得到签名的时候,把时间戳加进去是为了在一定程度上屏蔽了一些无效的请求,可以略去,也可以设计的更加严格。 如果想防止恶意的 api ddos 攻击,这一步验证肯定是不行的。需要做更多的验证,比如用户验证,ip 验证等。 可以参考 github 的 api 的设计 。它会在返回的 http 头信息里带上

X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999

表示这个接口在某一时间段内,该授权用户调用该接口的最大次数为5000次,该时间段内还剩余4999次。当然,这样的验证加上之后,在代码的执行效率上肯定会有所影响。

是否需要将 request_parameters 也加入到 sign 生成的算法之中?

也不是必须的,仅仅是为了请求的真实性,减少请求的伪造,比如 有人抓包拿到 http 请求之后,如果没有验证 sign 这步,那么别人就可以非常简单的修改请求的参数,而请求都会生效。

血的教训,自己经历的一个实际案例:

一个取消用户喜欢的标签的接口,该接口会向服务器端发送类似于 ids=1,2,3,4 这样的 request_parameters ,然后服务器端拿到这些 id 之后切割,然后将该用户和这些标签的关系从 user_tag 表中删除。某个周末,数据库服务器报警,而依照我们用户习惯,那个时间不存在流量高峰,这个报警很不正常,正准备处理,报警结束了,但是过了一段时间就有用户反应他们喜欢的标签都被删了。

通过查询数据库的慢日志,发现有很多注入的 sql。

DELETE FROM `user_tag` WHERE uid=4385328 AND tid=1 OR 14=14;
DELETE FROM `user_tag` WHERE uid=4385328 AND tid=1 OR 91=91;

原来 没有对切割之后的 id 没有做数字验证,估计黑客就是传的 ids=1 OR 14=14,2,3 ,而一个 delete 操作可能超时,他丫的就搞了很多次请求,真是够狠的。

幸运,数据库还有定时的打包备份,大部分用户的数据还是恢复了,同时修复了这一漏洞。

所以如果这里将 request_parameters 也加入到签名之中,就减少了伪造请求的可能性,但是无法杜绝,破坏者可能就非要黑你,又对逆向工程非常熟悉,找到我们加密算法的实现,依然可以未知出合法的签名,所以我们常说,服务器端永远不能相信客户端的请求都是安全的、合法的,需要做验证的都还是不能省略。

同时这( sign 算法)也造成了 api 接口调试的成本,api 测试工具必须也得实现那一套算法,或者是设置在开发环境下不做验证。我们在配置开发环境的时候则是 vpn 连测试服务器所在内网,然后进行测试,否则开发环境也存在被人利用的风险。

分割线--------------------------------------------------------------------------

好了,说实话,上面那位老兄的第六步没看太明白,根据APIkey check securitykey ,我理解securitykey 应该就是第一次握手生成的通常意义的token,

而这个APIkey则是类似于百度开发者那种key,是和用户绑定的,表示这个用户可以用我的api,每次请求都必须要有,

这个securitykey 是根据某种规则(加了时间戳作为salt),并且是基于APIkey生成的,这样才说的通。

那服务器端验证,先根据传过来的APIkey,生成securitykey,再和其他传过来的timestamp和request_parameters 和endpoint和前端采用同样的加密方法生成

一个sign,再和前端传过来的sign比较,一致就算pass,接下来就那securitykey 愉快地和服务器端(对称加密)消息通信啦。

黑客面临两个难点,一是要知道由APIkey生成securitykey的方法,二是要知道图中function2的加密算法,

然鹅,黑客如果在服务器端第一次给客户端APIkey和securitykey的时候就获取到它们两,而客户端的functions恰好又是js写的,那么这种方法也是然并卵的。

5:这个时候要讨论一下加密算法了。

对称加密(Symmetric Cryptography)

对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。

对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off(权衡)。

非对称加密(Asymmetric Cryptography)

非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人--银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。

目前最常用的非对称加密算法是RSA算法,是Rivest, Shamir, 和Adleman于1978年发明,他们那时都是在MIT

虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。 所以,结合方法4和方法5,正常的握手流程应该是这样的。

(1) 用户登录返回一个 公钥(publickey),一个APIkey作为用户识别key。

(2) 浏览器生成了一个随机数作为对称密钥(securitykey ), 并用公钥对自己的对称密钥加密,浏览器将加密后的对称密钥发送给服务器。

(3) 服务器使用私钥解密得到浏览器的对称密钥。

(4) 两边可以使用对称密钥来对沟通的内容进行加密与解密了。

这招应该能让黑客傻眼了吧。但前提是用户名和密码可别泄漏了。

最后再说一下soap和rest的适用场景,

其实SOA本质就是一种网络函数调用,如果我们的需求都可以抽象成资源,就可以用rest,而且抽象得越精确越好,

个人感觉,如今大多数项目都是对某些数据(对象)CRUD,即使对与工作流等偏数据处理类的应用,也是一种活动或处理的调用而已,

验证,log,异常处理都可以交给spring,那么我想选择rest的根本原因还是在于它的高效率上吧。

从resfful API设计到加密算法的更多相关文章

  1. javascript的api设计原则

    前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...

  2. (转载) RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  3. RESTful API 设计指南

    转自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机. ...

  4. GOTO Berlin: Web API设计原则

    在邮件列表和讨论区中有很多与REST和Web API相关的讨论,下面仅是我个人对这些问题的一些见解,并没有绝对的真理,InnoQ的首席顾问Oliver Wolf在GOTO Berlin大会上开始自己的 ...

  5. RESTful API 设计最佳实践

    背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...

  6. 我所理解的RESTful Web API [设计篇]

    <我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...

  7. 从英文变形规则计算到Restful Api设计

    ➠更多技术干货请戳:听云博客 一天在研究Restful API设计,命名的时候我总是很纠结,我相信大多数人也有这种感觉,不是说想不出来某个单词怎么写的问题,像我这种没事背单词背到13000词量的人也要 ...

  8. RESTful API 设计指南 (转)

    RESTful API 设计指南 2016-02-23 ImportNew (点击上方公号,可快速关注) 作者:阮一峰 链接:http://www.ruanyifeng.com/blog/2014/0 ...

  9. 基于资源的权限系统-API设计

    概述 权限系统需要和别的系统集成,因此,良好的API是易用性的保证. 这里只设计一些权限相关的核心 API,关于用户,组织,导入导出之类的后续再逐步补充 API 设计 围绕权限有以下 4 类 API: ...

随机推荐

  1. Excel应该这么玩——6、链接:瞬间转移

    上一篇中提到通过命名表格来管理基础数据,这样会让数据更规范.如果有很多个基础数据表,需要查找或者修改其中的一个,可以通过名称框中下拉来定位. 但是当表格较多的时候,通过下拉选择的方式就不是很好定位了. ...

  2. lucene中FSDirectory、RAMDirectory的用法

    package com.ljq.one; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStrea ...

  3. font-family:“微软雅黑” OR font-family:Microsoft Yahei

    sublime对中文编码支持的不好,可以考虑用后者.

  4. IOS响应式编程框架ReactiveCocoa(RAC)使用示例

    ReactiveCocoa是响应式编程(FRP)在iOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# :在网上看了几 ...

  5. Codefroces 750C:New Year and Rating(思维)

    http://codeforces.com/contest/750/problem/C 题意:有n场比赛,每场比赛有一个c,代表比赛结束后分数的增长情况,有一个d,代表这场比赛在div1或者div2打 ...

  6. javascript实现九九乘法表

    CSS代码部分: <style type="text/css"> table { width: 800px; height: 300px; border-collaps ...

  7. python 学习笔记十五 web框架

    python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. Python的WEB框架分为两类: 自己写socket,自 ...

  8. sql-ASCII函数运用

    declare @a int = ASCII('A') declare @b int = ASCII('F') declare @c int = 1 while(@a <= @b) begin ...

  9. Extjs MVC学习随笔01

    Extjs Mvc模式下的整个MVC框架体系即下图: 包含了Controller(实现方法层),Store(数据来源管理层),View(页面布局层).之所以用MVC我想是因为减轻针对某一页面的单一的J ...

  10. R语言拆分字符串

    R语言拆分字符串 aaa<-"aa;bb;cc"ccc<-strsplit(aaa,split=";") bbb<- unlist(strsp ...