API 双方认证探讨
开放 api 已是大势所趋。而 api 这种东西有个特点就是覆水难收。一旦公开出去了,被大量用户使用,一旦修改,就会让广大用户都掉坑里。所以,api 在设计之初就要尽量考虑周全,并预留扩展可能。
目前绝大多数 api 都是通过 http 协议访问。api 一般有两类,一类只涉及到提供方和使用者,另一类还涉及到最终用户。因此,前一类在认证上也只涉及两方,而后一类还涉及到用户授权,也就是通常使用的 OAuth。这里先说说第一类。比如 amazon aws 的 api、google 的地图 api 等的认证就属于这类。
双方认证的 api 通常的认证方式是使用一组 id 和密钥,用 id 来标记应用,用密钥来对请求做签名。id 和密钥一般是应用向服务方申请的。这样,服务费也可以控制 api 的使用。如果想停止某个用户访问 api,只需要取消这个用户的认证信息。即可。
举个例子,google 地图的 api,就是简单使用密钥对 url 做 HMAC_SHA1 签名。如:
$signature = hash_hmac("sha1",$url_to_sign, $key, true);
然后把签名编码后,追加在 url 后面访问。服务方根据请求中的 id 找到对应的密钥,同样做一遍签名,如果相等则认证通过。对于一些更复杂一些的 api ,请求还可能通过 HTTP header 、post body 来传递。此时,签名就需要把所有关键信息都一起签名。为了避免参数顺序的敏感性,即仅仅改变参数顺序就会影响签名结果,通常还会要求先对参数进行排序。amazon aws 的新版认证协议还对于一些关键参数改为了每次加入一个就签名一次。这恐怕也是因为 sha1 也已经没那么可靠了吧。
这是最简单的认证方式。使用这种方式,由于密钥并没有在网络上传递,hmac sha1 算法也是不可逆的,第三方无法冒充别的用户对自己的 url 进行签名。但是这种简单的方式有个缺点。同样的 url 在签名后是可以反复使用的。因此,如果恰好第三方需要的服务或数据和你的相同,那也可以直接复制你的 url 去用,花你的 money 、读你的数据。这也叫重放攻击。
为了避免或者减少重放攻击的危害,一些 api 把时间也作为了参数之一。签名的时候也把时间一起签进去。在服务端不仅要比较签名,还要请求的时间和服务端时间的差是否在许可范围,比如 15 分钟内。amazon aws 的 api 就是如此。这样,就算截获了一个请求,也顶多在 15 分钟内有效。不过由此带来的问题是,如果时钟偏差大了,就无法正常调用服务了。因此,客户端和服务端都必须严格对时。如在 linux 上开启 ntpd 。另外,对于 15 分钟内的重复攻击,仍然没有很好的办法。这时候,能做的也许就是在业务上减少由此可能带来的损失了。比如对 aws 来说,重复申请资源会因为重名而无法通过,而重复修改或删除资源请求通常也是没意义的。而另一些资源信息,仅在 15 分钟内可以重放,也无法获得新的有价值的数据。
如果真的在意这一点又该如何呢?以上方法都是在保持协议无状态前提下的。如果放弃这个前提,变成有状态协议,就有了别的方法。比如,可以引入一次性令牌来解决。首次访问前,先去请求一个一次性令牌,之后请求服务的签名的时候,把这个令牌也一起签名,并一起传递。服务端会检查该令牌是否仍然有效。请求后,会使原来的令牌失效,同时颁发一个新的一次性令牌。这看着是不是有点眼熟?有点像是 session 的实现方式吧。session 就是在客户端和服务端传递一个令牌来标示身份,在无状态协议中模拟状态的。第三方就算劫持到令牌,因为没有密钥,也没法加以利用。而拦截到的请求在使用一次后,也已经失效。这样就有效避免了重放攻击。但是,这样也是有代价的,如此一来,服务端就必须来维护这些会话。可能会占用大量资源,并有可能由此受到拒绝服务攻击。因此,多数服务都没有采用这种方式来认证。
以上的认证方式只适合用在服务端-服务端。而不适合用在客户度,如浏览器、移动端、桌面客户端等。在这些地方使用双方认证 API ,就不可避免的要把应用的密码携带分发。这是很危险的。一旦有人从中破解获取了你的密钥,一切就全完蛋了。这时候,要通知所有终端更换密钥也是件麻烦事。通常,都需要使用应用自己的服务端作为代理来访问。至少是通过应用自己的服务端来计算签名。但是这对于一些服务,比如云存储,代价就有点大了,这样一来,应用就还是得在自己的服务器上走大量的流量。要解决这样的问题,一些 API 提供方给了另外的一种认知方式。
应用先给自己的每个用户生成一个 uid,然后用密钥对其签名得到用户密钥,把应用 id,uid,签名保存在客户端分发。从客户端发起请求时,带上应用 id,uid,使用用户密钥签名。服务端则用同样的方式验证,并可以通过 uid 来做数据的访问控制。这样一旦客户端被破解,也只会影响一个终端用户,而不是像之前一样,所有用户的信息都收到威胁。
转载: http://xiezhenye.com/2013/03/api-%E5%8F%8C%E6%96%B9%E8%AE%A4%E8%AF%81%E6%8E%A2%E8%AE%A8.html
API 双方认证探讨的更多相关文章
- RESTful Api 身份认证中的安全性设计探讨
REST 是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 ...
- Web APi之认证(Authentication)两种实现方式【二】(十三)
前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...
- RESTful Api 身份认证安全性设计
REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 H ...
- Web APi之认证(Authentication)两种实现方式后续【三】(十五)
前言 之前一直在找工作中,过程也是令人着实的心塞,最后还是稳定了下来,博客也停止更新快一个月了,学如逆水行舟,不进则退,之前学的东西没怎么用,也忘记了一点,不过至少由于是切身研究,本质以及原理上的脉络 ...
- 关于RESTFUL API 安全认证方式的一些总结
常用认证方式 在之前的文章REST API 安全设计指南与使用 AngularJS & NodeJS 实现基于 token 的认证应用两篇文章中,[译]web权限验证方法说明中也详细介绍,一般 ...
- 转 Web APi之认证(Authentication)两种实现方式【二】(十三)
前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再废叙述废话. 序言 对于所谓的认证说到 ...
- Web APi之认证
Web APi之认证(Authentication)两种实现方式后续[三](十五) 前言 之前一直在找工作中,过程也是令人着实的心塞,最后还是稳定了下来,博客也停止更新快一个月了,学如逆水行舟,不 ...
- spring cloud+dotnet core搭建微服务架构:Api授权认证(六)
前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...
- spring cloud+.net core搭建微服务架构:Api授权认证(六)
前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...
随机推荐
- Java——线程间通信问题
wait和sleep区别: 1.wait可以指定时间可以不指定. sleep必须指定时间. 2.在同步时,对cpu的执行权和锁的处理不同. wait:释放执行权,释放锁. ...
- 论文笔记之:Decoupled Deep Neural Network for Semi-supervised Semantic Segmentation
Decoupled Deep Neural Network for Semi-supervised Semantic Segmentation xx
- git 教程 ,常用命令
Git使用手册 http://www.cnblogs.com/lantingji/p/5942721.html git官网 https://git-scm.com/ Git的奇技淫巧 http://w ...
- Code First 约定
Code First 约定 借助 Code First,可通过使用 C# 或 Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code Fi ...
- Web前端开发笔试&面试_03
WL: 1.如何显示.隐藏一个dom对象? 2.如何将一个网页中的内容水平置中?写出重要的html标签和css. (css:#content{align:center;float:left;}html ...
- 在Windows上安装Maven
下载 Maven 最新版本. http://maven.apache.org/download.cgi 1,下载包后,解压到相应特定位置. 2,将 [解压位置]/bin 加入到Path 3, ...
- 一、PHP MongoDB Windows7_64位安装与配置
NoSQL现在非常的流行了,由于我所在的公司环境问题,目前还用不到这种数据库,出于好奇,翻了翻资料,也算自学了一下.在此做下记录. 我的本机环境:APMServ5.2.6,PHP肯定就是5.2了. 1 ...
- Codeigniter MongoDB类库
安装方法:1.将mongodb.php 放到config目录2.将Mongo_db.php放到library目录 使用方法: $this->mongo_db->where_gte('age ...
- java读写文件大全
java读写文件大全 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中 write(char[] ch,int o ...
- IDEA快捷键大全
IntelliJ Idea 常用快捷键列表 Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Sh ...