[译]移动API安全终极指南

文章主要讲了移动api调用的受权和验证问题,原文连接:The Ultimate Guide to Mobile API Security
android

移动API的使用是Stack Overflow和 Stormpath支持频道上常常出现的话题。这是一个已经被解决的问题,可是须要大量必要的知识和充足的理解才能很好地实现。ios

这篇文章可以让你了解到有关于在移动设备上安全的调用Restful API的一切内容,不管你是在构建一个须要访问Restful API的移动app,仍是正在写Restful API而且打算和移动app开发者进行交互。web

个人目标不只仅是解释如何确保移动开发者可以安全调用你的Restful API,同时还解释整个凭证从开始到结束的交换过程,以及如何从安全漏洞中恢复等等。数据库

移动API安全问题api

在咱们投身去探究如何确保移动开发者可以安全调用Restful API以前,让咱们先讨论一下什么使得移动认证有别于传统的API认证。浏览器

API认证最基本的形式就是通常为咱们所知的HTTP Basic Authentication安全

对于API服务开发者和使用它的人来讲,它的工做方式是很是简单的:服务器

· 开发者会获取到一个API key(通常是ID和Secret)。这个API key通常像这样:3bb743bbd45d4eb8ae31e16b9f83c9ba:ffb7d6369eb84580ad2e52ca3fc06c9d。app

· 开发者有责任将API key存放在一个安全的地方,没有人能够获得它。curl

· 开发者发起API请求时,须要把API key放到HTTP Authorization header中,同时带有关键词Basic(也就是用户名和密码都使用base64加密)。下面展现了开发者在调用API时如何指定API key进行认证,使用命令行工具cURL。

$ curl --user 3bb743bbd45d4eb8ae31e16b9f83c9ba:ffb7d6369eb84580ad2e52ca3fc06c9d https://api.example.com/v1/test

cURL工具能够将获取到的API证书用base64加密,而后建立一个HTTP Authorization hearder,以下所示:Basic M2JiNzQzYmJkNDVkNGViOGFlMzFlMTZiOWY4M2M5YmE6ZmZiN2Q2MzY5ZWI4NDU4MGFkMmU1MmNhM2ZjMDZjOWQ=.。而API服务器将会从HTTP Authorization hearder中获取字符串,而后用base64解密,得到ID和Secret,验证经过后再处理相应的API请求。

HTTP Basic Authentication虽然简单,可是很好用。开发者在调用API时附带API key能够很好地与API服务器进行验证。

可是,因为移动app没法安全存储API秘钥,使得HTTP Basic Authentication并非一个很好的选择。同时,HTTP Basic Authentication要求在每次请求时使用原始的API keys,这就致使了keys会被长期使用,这是不安全的。

所以在大多数状况下,这种验证方式是不切实际的,由于没法安全的将API keys嵌入到分配给许多用户的移动app中。

好比说,你将API keys嵌入到你所构建的移动app中,然而一个精明的用户可以对你app进行反向工程,获取到keys,从而滥用你的API服务。

这就是为何在不可信的环境中,HTTP Basic Authentication不是一个最好的选择,例如web浏览器和移动app。

注意:和其余全部认证协议同样,HTTP Basic Authentication必须在SSL之上使用。

为移动安全引入OAuth2.0

在此以前你可能据说过OAuth,而且在争论它是什么和它并无足够的好。那么让咱们明确:OAuth2是一个优秀的协议,在不受信任的设备中用于保护API服务的安全。它经过一种咱们称之为token的认证方式来对移动用户进行认证。

下面咱们从用户的角度OAuth2 token认证的工做方式。

1. 用户打开移动app,输入帐号和密码。

2. 移动app发送一个带有用户的用户名和密码的POST请求到API服务器,服务器进行验证,成功后返回一个code。

3. 移动app经过code向认证服务器发送请求,认证成功后为用户生成一个一段时间后就会过时的access token。

4. 将access token存储在移动设备本地,就像一个可以访问API服务的API key同样。

5. 一旦access token过时就再也不工做,须要再提示用户输入用户名密码,重复1的步骤。

之因此说OAuth2在保障APIs安全上是极好的,是由于咱们不须要在一个不安全的环境中长期存储API keys,取而代之的是生成一个临时的access tokens。这能够抵御一些潜在的攻击。

如今,当您的API服务生成您的移动应用程序须要的Oauth2 token时,您固然须要将其存储在您的移动应用程序中。

可是存在哪里?!

token存储的位置取决于你所处的开发平台。若是你开发的是一个android app,你会将access tokens存储在SharedPreferences中,若是你的IOS开发者,你将会将access tokens存在Keychain中。

若是你仍然存在疑问,下面这两个Stack Overflow的posts可能会很是有用,它详细阐述了如何在移动app中存储access token。

· Where should I store access tokens on Android?

· Where should I store access tokens on iOS?

如今你应该对OAuth2有所了解,为何要使用它,以及它的工做原理。

Access Tokens

让咱们来讨论一下access tokens。他们究竟是什么?是一串随机生成的数字?是uuid?仍是别的?
这是一个很好的问题。
这里是一个比较短的答案:access token在技术上你任何你想要的字符串:

· 一个随机数

· 一个随机字符串

· 一个uuid

· 更多

更详细的解释:

· 为客户端而生成的。

· 验证token的全部者是你(使用强的签名)

· 存在过时时间。
有了以上的解释,你可能会但愿去遵照必定的规范。为了避免本身处理这些,你能够直接使用JWT(Json Web Token)。这是一个比较新的规范,容许你生成access token。这个规范(RFC7519)知足一下几点:

· 能够为客户端生成

· 能够被建立者验证

· 在某一具体时间后自动过时

· 能够容纳可变的JSON信息

· 无需查询API服务,容许用户本地验证API凭证,从而减小对API调用的次数。

JWTs看起来像随机生成的字符串,在使用的时候你能够像字符串那样存储他们。这使得取代传统的access token而使用JWTs很是方便,毕竟它们基本上都是相同的,而JWT有更多的优点。

JWTs老是以加密的方式被验证。他们工做的方式以下:

· 在API服务器的某处存储一个安全随机字符串。通常是一个比较长的随机字符串(40个字符左右差很少)

· 当你建立一个新的JWT时,你须要将这个随机串传递个JWT类库来签署token,同时带有一些你想存储的数据,例如用户ID,email等等。

· token将会被生成,看起来像header.claims.signature——header、claims和signature都是base64加密的字符串。

· 讲生成的token给用户,通常是API的使用者,例如移动app。

如今从移动客户端中,你能够看到存储在JWT中的任何东西。so若是我有一个JWT,我能够轻松地查看到里面包含的JSON数据,一般以下所示:

{

"user_id": "e3457285-b604-4990-b902-960bcadb0693",

"scope": "can-read can-write"

}

固然,这是一个100%虚构的例子,可是你能够从中知道,若是你获得这个JWT的副本,你也能够看到存储在里面的JSON信息。

JWT标准支持自动的过时标记,所以你也可以验证这个JWT是有效的。不管你使用什么开发语言,只要在使用JWT库,你就能验证JWT的有效性直到过时!

这意味着,若是你使用JWT访问API服务,则只需验证JWT,就能够知道你的API调用是否能够工做,不须要API调用。

如今,一旦你有了一个有效的JWT,你也能够在服务器端用它作很酷的事情。

假设您已经向移动app发布了一个包含如下数据的JWT:

{

"user_id": "e3457285-b604-4990-b902-960bcadb0693",

"scope": "can-read can-write"

}

假设移动app上有恶意代码可以修改你的JWT,好比说:

{

"user_id": "e3457285-b604-4990-b902-960bcadb0693",

"scope": "can-read can-write can-delete"

}

若是这个修改过的token被发送到咱们的API服务器会发生什么?它会起做用吗?咱们的服务器会接受这个修改的JWT吗?

注意!!
当你的API服务收到JWT并进行验证时,它会作如下几件事情:

· 经过使用只有服务器才知道的随机生成的字符串来检查token,确保它没有被篡改。若是JWT彻底被修改,这个检查就会失败,你会知道有人正在试图作一些使人讨厌的事情。

· 同时服务器会检查JWT的过时时间,确保它的合法性。so若是客户端用一个已通过期的token来进行请求,你能够马上拒绝。

这是很好的功能,由于它使处理验证/到期/安全更简单。

在使用JWTs时,你惟一须要记住的就是:不要在JWT中存储敏感信息。

谨记以上提到的规则,那么在使用JWTs时就不会出错了。

一般你会存一下两条信息在JWTs中:

· 用户账户的某种惟一ID。这样,当您收到此JWT进行身份验证时,您能够从用户数据库中查找此用户。

· 用户权限。固然若是构建的是全部用户都能访问的简单的API,那么这个多是没必要要的。可是经过这个,用户就不须要经过看API文档来了解本身能够作什么,不能够作什么,只须要根据看本身的JWT就能够。

以上就是有关于JWT的所有。

相关文章
相关标签/搜索