开放 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 双方认证探讨的更多相关文章

  1. RESTful Api 身份认证中的安全性设计探讨

    REST 是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 ...

  2. Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...

  3. RESTful Api 身份认证安全性设计

    REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 H ...

  4. Web APi之认证(Authentication)两种实现方式后续【三】(十五)

    前言 之前一直在找工作中,过程也是令人着实的心塞,最后还是稳定了下来,博客也停止更新快一个月了,学如逆水行舟,不进则退,之前学的东西没怎么用,也忘记了一点,不过至少由于是切身研究,本质以及原理上的脉络 ...

  5. 关于RESTFUL API 安全认证方式的一些总结

    常用认证方式 在之前的文章REST API 安全设计指南与使用 AngularJS & NodeJS 实现基于 token 的认证应用两篇文章中,[译]web权限验证方法说明中也详细介绍,一般 ...

  6. 转 Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再废叙述废话. 序言 对于所谓的认证说到 ...

  7. Web APi之认证

    Web APi之认证(Authentication)两种实现方式后续[三](十五)   前言 之前一直在找工作中,过程也是令人着实的心塞,最后还是稳定了下来,博客也停止更新快一个月了,学如逆水行舟,不 ...

  8. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  9. spring cloud+.net core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

随机推荐

  1. PHP安全配置

    vi /etc/php.ini #编辑 date.timezone = PRC #在946行把前面的分号去掉,改为date.timezone = PRC disable_functions = pas ...

  2. 15款Chrome浏览器插件让设计师告别拖延症

    秋高气爽,分享一大波有效帮助设计师提高工作效率的Chrome浏览器扩展程序! 高效是另一种王道 无论是在工作中,还是在生活中,有些词我们说来就满满正能量,而另外一些话提起就很沮丧,后者如拖延症,前者如 ...

  3. (转)A Beginner's Guide To Understanding Convolutional Neural Networks Part 2

    Adit Deshpande CS Undergrad at UCLA ('19) Blog About A Beginner's Guide To Understanding Convolution ...

  4. shell之echo与printf和颜色

    在用户的bashrc中添加一行export来修改提示符.

  5. SSH客户端(如PuTTY)ssh远程登录Linux非常慢的解决方法

    转:http://blog.useasp.net/archive/2014/05/19/solved-the-problem-of-ssh-client-such-as-putty-remote-lo ...

  6. ajax方法完整的事件流

  7. discuz 发布分类信息,能不能设置单版块去掉“发帖子”(默认点发帖后为自定义的默认分类信息模版)

    http://www.discuz.net/forum.php?mod=viewthread&tid=3365198&page=1#pid26849156

  8. jmeter制造安全证书

    对安全性有要求的网站一般使用https来加密传输的请求和响应.https离不开证书,关于证书不在多说.Apache的HttpClient支持https, 下面是官方的样例程序,程序中使用了my.sto ...

  9. Oracle RAC环境的日志体系

    转摘:http://blog.itpub.net/22664653/viewspace-722463/ 在Oracle RAC环境中比单个系统的日志体系要复杂:见下图: 简单介绍一下有关Oracle集 ...

  10. IOS开发-UI基础-视图

    //------------------------------UIWindow--------------------------// 1.UIWindow:是 UIView 的子类,用于管理.协调 ...