【问题标题】:Security of REST authentication schemesREST 身份验证方案的安全性
【发布时间】:2010-10-02 01:06:58
【问题描述】:

背景:

我正在为 REST Web 服务设计身份验证方案。这并不“真的”需要安全(它更像是一个个人项目),但我想让它尽可能安全,就像锻炼/学习体验一样。我不想使用 SSL,因为我不想麻烦,而且主要是设置费用。

这些 SO 问题对我开始很有帮助:

我正在考虑使用Amazon S3's authentication 的简化版本(我喜欢OAuth,但它对我的需要来说似乎太复杂了)。我将服务器提供的随机生成的nonce 添加到请求中,以防止重放攻击。

回答问题:

S3 和 OAuth 都依赖于对请求 URL 以及一些选定的标头进行签名。 他们都不为 POST 或 PUT 请求签署请求正文。这是否容易受到中间人攻击,它会保留 url 和 headers 并用攻击者想要的任何数据替换请求正文?

似乎我可以通过在已签名的字符串中包含请求正文的哈希来防止这种情况。这安全吗?

【问题讨论】:

  • Amazon S3 可以包含 Content-MD5 作为标头字符串的一部分,以防止您描述的 MITM 攻击。
  • MD5 是一个非常弱的哈希函数,多年来一直不鼓励使用它:en.wikipedia.org/wiki/MD5。现在使用 SHA2。 MD5 是身份危机猪的口红。
  • Startcom 提供免费的 SSL 证书,不会在主流浏览器中抛出证书警告
  • @SeanKAnderson(咆哮:当互联网受到间谍机构的围攻时,我发现人们谈论 99.99999%s 的方式很荒谬,间谍机构在 2008 年就已经自动化了很多攻击——这是一种奇怪的方式处理一个真正的问题——“Naaah,不会有问题;我奶奶将无法破解它”
  • @Plato 这些天我推荐 LetsEncrypt 以获得免费的 SSL 证书

标签: rest authentication oauth amazon-s3 rest-security


【解决方案1】:

之前的回答仅在数据传输的上下文中提到 SSL,实际上并未涵盖身份验证。

您实际上是在询问如何安全地验证 REST API 客户端。除非您使用 TLS 客户端身份验证,否则 SSL 单独 不是 REST API 的可行身份验证机制。没有客户端身份验证的 SSL 仅对 服务器 进行身份验证,这与大多数 REST API 无关,因为您确实想要对 客户端 进行身份验证。

如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 1.0a 甚至 HTTP 基本身份验证(但仅通过 SSL) .

这些方案验证请求是由预期的人发送的。 TLS (SSL)(无客户端身份验证)确保通过网络发送的数据不会被篡改。它们是独立但互补的关注点。

对于那些感兴趣的人,我已经扩展了一个关于 HTTP Authentication Schemes and how they work 的 SO 问题。

【讨论】:

【解决方案2】:

REST 意味着使用网络标准,网络上“安全”传输的标准是 SSL。其他任何东西都会有点时髦,并且需要为客户端进行额外的部署工作,而客户端必须有可用的加密库。

一旦您承诺使用 SSL,原则上就不需要花哨的身份验证了。您可以再次使用 Web 标准并使用 HTTP 基本身份验证(与每个请求一起发送的用户名和秘密令牌),因为它比复杂的签名协议简单得多,并且在安全连接的上下文中仍然有效。您只需要确保密码永远不会超过纯文本;因此,如果曾经通过纯文本连接接收到密码,您甚至可以禁用密码并邮寄给开发人员。您还应该确保在收到凭据时不会在任何地方记录,就像您不会记录常规密码一样。

HTTP Digest 是一种更安全的方法,因为它可以防止秘密令牌被传递;相反,它是服务器可以在另一端验证的哈希值。尽管如果您采取了上述预防措施,对于不太敏感的应用程序可能会有点过分。毕竟,用户登录时的密码已经以纯文本形式传输(除非您在浏览器中进行了一些奇特的 JavaScript 加密),同样,他们在每次请求时的 cookie。

请注意,对于 API,客户端最好传递令牌(随机生成的字符串)而不是开发人员登录网站时使用的密码。因此,开发人员应该能够登录您的站点并生成可用于 API 验证的新令牌。

使用令牌的主要原因是如果它被泄露,它可以被替换,而如果密码被泄露,所有者可以登录开发者的帐户并使用它做任何他们想做的事情。代币的另一个优势是您可以向同一个开发人员发行多个代币。可能是因为他们有多个应用程序,或者因为他们想要具有不同访问级别的令牌。

(已更新以涵盖仅使用 SSL 进行连接的含义。)

【讨论】:

  • 我认为您可以以每年 30 美元的价格获得 GoDaddy ssl 证书。我很震惊地看到 Verisign SSL 证书的价格是多少(如果我没记错的话,每年 600 美元或其他东西?)但是 GoDaddy 选项是完全可行的。
  • 除非您使用 SSL/TLS 相互认证,并且用户/客户端使用的证书是服务器信任的,否则您还没有将用户认证到服务器/应用程序。您需要做更多的事情来验证用户对服务器/应用程序的身份。
  • Ryan:与您使用 Django 或 Rails 等 Web 应用程序框架生成响应所使用的相比,如今的 SSL 加密只需要非常少量的处理能力。
  • startcom 的证书是免费的并且得到广泛认可。 cacert.org 是一个开放的替代方案,但认可度较低
  • 这并没有解决关于身份验证的问题。
【解决方案3】:

事实上,原始的 S3 身份验证确实允许对内容进行签名,尽管 MD5 签名较弱。您可以简单地强制他们在 HMAC(要签名的字符串)中包含 Content-MD5 标头的可选做法。

http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

他们新的 v4 身份验证方案更加安全。

http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

【讨论】:

    【解决方案4】:

    或者您可以使用已知的解决方案来解决此问题并使用 SSL。自签名证书是免费的,是个人项目吗?

    【讨论】:

    • 自签名证书是免费的,但 AFAIK 你仍然需要一个静态 IP。
    • @dF 除了商业付费证书的某些许可要求外,没有静态 IP 的要求。
    • 如果您可以控制两端(客户端和服务器)的证书存储,这可能是一个可行的选择,但是...证书管理和分发在生产环境中可能比在开发环境中复杂得多.在做出承诺之前,请务必了解此替代方案的复杂性。
    【解决方案5】:

    如果您需要将正文的哈希值作为 URL 中的参数之一,并且该 URL 是通过私钥签名的,那么中间人攻击只能将正文替换为以下内容:将生成相同的哈希。至少现在很容易使用 MD5 哈希值,当 SHA-1 被破坏时,你就明白了。

    为了保护正文不被篡改,您需要对正文进行签名,中间人攻击不太可能破解该签名,因为他们不知道加密的私钥生成签名。

    【讨论】:

    • 想出一个将生成与有效内容相同的 md5 哈希的字符串可能比它应该的要容易得多,但是想出一个哈希到相同值的有效内容的邪恶版本是仍然非常困难。这就是为什么 md5 不再用于密码哈希,但仍用于验证下载的原因。
    【解决方案6】:

    请记住,您的建议会使客户端难以与服务器通信。他们需要了解您的创新解决方案并相应地加密数据,这种模型对于公共 API 来说并不是那么好(除非您是 amazon\yahoo\google..)。

    无论如何,如果您必须加密正文内容,我建议您查看现有的标准和解决方案,例如:

    XML 加密(W3C 标准)

    XML Security

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多