34

我必须制定一个计划来开发一个 RESTful API (Python/Flask),它可以被我们未来的 Web 应用程序 (Angularjs) 和移动应用程序 (iOS/Android) 使用。

我已经研究了三天,并遇到了几种情况:使用 HTTPS 是以下方法之上的一种方法,以使其更安全。但是 https 速度较慢,这可能意味着我们需要更快、更昂贵的服务器。

  1. 对于对 API 的每个请求,使用 Basic-Http-Auth 并通过网络以纯格式(但 https)发送用户名/密码。
  2. 使用 Digest-Auth,它是密码的哈希,并且跟踪将是自动的这将适用于网络应用程序,但是我无法确认 iPhone 和 Android 是否会本机支持它。如果他们这样做,那可能是一个简单的解决方案!
  3. 使用自定义 http 标头,我将在成功身份验证后在 http 标头中发送自定义 Auth 字符串。但是我必须确保为用户提出的每个请求发送此身份验证代码。这使它与 1) 完全一样,不同之处在于不使用普通密码,并且身份验证代码可以过期而没有任何风险。同样有问题的是身份验证代码的跟踪,它不再像 2 中那样自动化)
  4. 使用 OAuth 是一种选择。但是设置起来相当困难。如果没有更好的方法,也许这是唯一的方法?
  5. 如这篇精彩的文章中所述,保护像 Amazon S3 这样的 API 。简而言之,他说服务器和客户端都知道一个私钥,他们将使用它来散列通信。这就像黑帮握手一样,如果他知道黑帮握手,您只会信任送货员。进一步降低有人问的评论:

如何在纯 HTML5 应用程序中保持私钥“安全”?

你完全正确;在纯 HTML5 (JS/CSS/HTML) 应用程序中,没有保护密钥。您将通过 HTTPS 进行所有通信,在这种情况下您不需要密钥,因为您可以使用标准 API_KEY 或其他友好标识符安全地识别客户端,而无需 HMAC 或复杂性。

所以换句话说,首先将这种方法用于网络应用程序甚至没有意义。老实说,我也不明白这应该如何在移动设备上工作。用户下载我们的应用程序,我如何将私钥从 iphone 发送到服务器?我转移它的那一刻,它就会受到损害。

我研究得越多,我就越犹豫不决。

我希望问一些以前做过这件事的专业人士,并可以分享他们的经验。非常感谢

4

3 回答 3

67

您似乎将两个不同的概念混淆/合并在一起。我们开始讨论加密流量 (HTTPS),然后我们开始讨论管理经过身份验证的会话的不同方法。在安全应用程序中,这些不是相互排斥的任务。似乎还可能存在对会话管理如何影响身份验证的误解。在此基础上,我将提供有关 Web 应用程序/Web api 会话管理、身份验证和加密的入门知识。

介绍

会话管理

HTTP 事务默认是无状态的。HTTP 没有指定任何方法让您的应用程序知道 HTTP 请求已从特定用户发送(无论是否经过身份验证)。

对于健壮的 Web 应用程序,这是不可接受的。我们需要一种方法来关联跨多个请求发出的请求和数据。为此,在对服务器的初始请求时,需要为用户分配一个“会话”。通常会话具有某种发送给客户端的唯一 ID。客户端随每个请求发送该会话 ID,服务器使用每个请求中发送的会话 ID 为用户正确准备响应。

重要的是要记住,“会话 ID”可以称为许多其他东西。其中一些示例是:会话令牌、令牌等。为了保持一致性,我将在此响应的其余部分使用“会话 ID”。

来自客户端的每个 HTTP 请求都需要包含会话 ID;这可以通过多种方式完成。流行的例子是:

  1. 它可以存储在 cookie 中 - 当前域的 cookie 会在每次请求时自动发送。
  2. 它可以在 URL 上发送 - 每个请求都可以在 URL 上发送会话 ID,不建议因为会话 ID 将保留在客户端历史记录中
  3. 它可以作为 HTTP 标头发送 - 每个请求都需要指定标头

大多数 Web 应用程序框架都使用 cookie。但是,依赖 JavaScript 和单页设计的应用程序可能会选择使用 HTTP 标头/将其存储在服务器可观察到的其他位置。

请务必记住,通知客户端其会话 ID 的 HTTP 响应以及包含会话 ID 的客户端请求是完全纯文本且 100% 不安全的。为了解决这个问题,所有 HTTP 流量都需要加密;这就是 HTTPS 的用武之地。

同样重要的是要指出我们还没有讨论将会话链接到我们系统中的特定用户。会话管理只是将数据与访问我们系统的特定客户端相关联。客户端可以处于经过身份验证和未经身份验证的状态,但在这两种状态下,它们通常都有一个会话。

验证

身份验证是我们将会话链接到系统中的特定用户的地方。这通常由用户提供凭据的登录过程处理,这些凭据经过验证,然后我们将会话链接到系统中的特定用户记录。

反过来,用户通过访问控制列表和访问控制条目(ACL 和 ACE)与细粒度访问控制的权限相关联。这通常被称为“授权”。大多数系统总是同时具有身份验证和授权。在一些简单的系统中,所有经过身份验证的用户都是平等的,在这种情况下,您将无法通过简单身份验证获得授权。有关此问题的更多信息超出了此问题的范围,但请考虑阅读有关 ACE/ACL 的信息。

可以将特定会话标记为以不同方式代表经过身份验证的用户。

  1. 他们的会话数据存储在服务器端可以存储他们的用户 ID/其他一些标志,表示该用户已被验证为特定用户
  2. 另一个用户令牌可以像会话 id 一样发送到客户端(通过未加密的 HTTP 与发送未加密的会话 id 一样不安全)

任何一个选项都很好。它通常归结为您正在使用的技术以及它们默认提供的内容。

客户端通常启动身份验证过程。这可以通过将凭据发送到特定 url(例如 yoursite.com/api/login)来完成。但是,如果我们想成为“RESTful”,我们通常会通过某个名词引用资源并执行“创建”操作。这可以通过要求将凭据发布到 yoursite.com/api/authenticatedSession/ 来完成。想法是创建一个经过身份验证的会话。大多数站点只是将凭据发布到 /api/login 等。这与“真正的”或“纯粹的”RESTful 理想背道而驰,但大多数人认为这是一个更简单的概念,而不是将其视为“创建经过身份验证的会话”。

加密

HTTPS 用于加密客户端和服务器之间的 HTTP 流量。在依赖认证用户和未认证用户的系统上,所有依赖用户认证的流量都需要通过 HTTPS 加密;没有办法解决这个问题。

这样做的原因是,如果您对用户进行身份验证,与他们共享一个秘密(他们的会话 ID 等),然后开始在纯 HTTP 中展示该秘密,他们的会话可能会被中间人攻击劫持。黑客将等待流量通过观察到的网络并窃取秘密(因为它是通过 HTTP 的纯文本),然后假装是原始客户端启动与您的服务器的连接。

人们解决这个问题的一种方法是将请求远程 IP 地址与经过身份验证的会话相关联。单独这样做是无效的,因为任何黑客都能够在他们的虚假请求中欺骗他们的请求远程 IP 地址,然后观察你的服务器发回的响应。大多数人会争辩说,除非您正在跟踪历史数据并使用它来识别特定用户的登录模式(如 Google 所做的那样),否则这甚至不值得实施。

如果您需要在 HTTP 和 HTTPS 部分之间拆分站点,则 HTTP 流量必须不发送或接收会话 ID 或任何用于管理用户身份验证状态的令牌。请勿在非 HTTPs 请求/响应中发送敏感的应用程序数据,这一点也很重要。

在 Web 应用程序/API 中保护数据的唯一方法是加密您的流量。

您的主题一一

Basic-Http-Auth

  • 身份验证:是
  • 会话管理:否
  • 加密:否

这是一种仅通过 Web 资源进行身份验证的方法。基本身份验证通过 URL 标识的资源对使用进行身份验证。这是 Apache HTTP Web Server 最常用的实现方式,它使用基于 .htaccess 的目录/位置身份验证。每个请求都必须发送凭据;客户通常会为用户透明地处理此问题。

其他系统可以使用基本身份验证作为身份验证模式。但是,使用 Basic-Http-Auth 的系统提供身份验证和会话管理,而不是 Basic-Http-Auth 本身。

  • 这不是会话管理。
  • 这不是加密;内容和凭据几乎是 100% 纯文本
  • 这不会保护应用程序的 HTTP 请求/响应的内容。

摘要认证

  • 身份验证:是
  • 会话管理:否
  • 加密:否

这与 Basic-Http-Auth 完全相同,只是添加了一些简单的 MD5 消化。不应依赖此摘要而不是使用加密。

  • 这不是会话管理。
  • 这不是加密;摘要很容易被破坏
  • 这不会保护应用程序的 HTTP 请求/响应的内容。

身份验证

  • 身份验证:是
  • 会话管理:否
  • 加密:否

OAuth 只是让您有一个外部服务验证凭据。之后,由您来管理/处理向您的 OAuth 提供者提出的身份验证请求的结果。

  • 这不是会话管理。
  • 这不是加密;您的网站流量仍然是纯文本。由于 HTTPS 限制,身份验证过程将是安全的,但您的应用程序仍然容易受到攻击。
  • 这不会保护应用程序的 HTTP 请求/响应的内容。

Gangster Handshake /自定义 HTTP 标头

  • 身份验证:是,可能
  • 会话管理:是的,可能
  • 加密:否

“自定义 HTTP 标头”是“Gangster Handshakes”的一种;因此,我将使用相同的部分来讨论它们。唯一的区别是“自定义 HTTP 标头”指定了 hanshake(会话 ID、令牌、用户身份验证令牌等)的存储位置(即在 HTTP 标头中)。

需要注意的是,这些没有指定如何处理身份验证,也没有指定如何处理会话管理。它们本质上描述了会话 ID/身份验证令牌的存储方式和位置。

身份验证需要由您的应用程序或通过第三方(例如 OAuth)处理。会话管理仍需要实施。有趣的是,如果您愿意,您可以选择将两者合并。

  • 这不是加密;您的网站流量仍然是纯文本。如果您使用 OAuth,由于 HTTPS 限制,身份验证过程将是安全的,但您的应用程序仍然容易受到攻击。
  • 这不会保护应用程序的 HTTP 请求/响应的内容。

你需要做什么

...我强烈建议您确保您了解强大的安全 Web 应用程序需要以下内容:

  1. 加密(HTTPS 几乎是您唯一的选择)
  2. 会话管理
  3. 认证/授权

授权依赖于身份验证。身份验证依赖于会话管理和加密确保会话不被劫持并且凭据不被截获。

烧瓶登录

我认为您应该将烧瓶登录视为避免重新实现轮子的一种方式。我个人从未使用过它(我在 python 中将金字塔用于 Web 应用程序)。但是,我之前在 web 应用程序/python 板上看到过它。它处理身份验证和会话管理。通过 HTTPS 抛出您的 Web api/应用程序,您就拥有了所有三个(加密、会话管理和用户身份验证)。

如果您不/不能使用flask-login,请准备好自己编写,但首先要研究如何创建安全的身份验证机制。

如果可能的话,如果您不了解如何编写身份验证程序,请在未先了解黑客如何使用基于模式的攻击、定时攻击等之前不要尝试。

请加密您的流量

...超越您可以避免使用带有一些“聪明”令牌使用的 HTTPS 的想法。摆脱应该避免使用 HTTPS/加密的想法,因为它“速度慢”、进程密集等。它是进程密集型的,因为它是一种加密算法。确保用户数据和应用程序数据安全的需要始终是您的首要任务。您不想经历通知用户他们的数据已被泄露的恐惧。

于 2013-06-03T20:44:33.383 回答
1

使用 HTTPS。它(略微)较慢,但是您在相对较短的投资时间内(购买 SSL 证书并将您的 URL 从 http 更改为 https)从中获得的安全性是值得的。如果没有 HTTPS,您将面临用户会话在不安全的公共网络上被劫持的风险,而这对某人来说非常容易

于 2013-05-14T00:17:32.747 回答
1

https 它比较慢,但不是。只有握手更慢。对我们来说,最大的问题是维护服务器-移动端的密钥对和权利。我们也实现了消息摘要。问题是:很难正确设置 php-android-ios 版本。完成此操作后(一个参数需要更改最初建议 Google 仅在 android 端产生的结果)问题将出在低端设备上:CPU 使用率高,解密加密过程慢,比 https 慢很多,特别是当您需要转换 10kb 字符串时(可能需要几分钟)。

如果我不将美国国家航空航天局的数据传输到哈马斯,那么我会通过简单的 HTTP 进行非常简单的加密:比如反转比特左右......

于 2013-05-13T10:49:04.597 回答