233

背景:

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

这些 SO 问题对我开始特别有用:

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

要解决这个问题:

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

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

4

6 回答 6

171

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

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

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

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

对于那些感兴趣的人,我已经扩展了关于HTTP 身份验证方案及其工作原理的 SO 问题。

于 2012-05-11T19:47:08.407 回答
60

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

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

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

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

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

(已更新以涵盖仅建立 SSL 连接的含义。)

于 2009-01-28T20:57:33.903 回答
8

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

于 2009-01-28T13:52:06.710 回答
5

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

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

于 2009-01-28T06:37:07.480 回答
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

于 2013-03-10T06:52:52.567 回答
1

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

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

XML 加密(W3C 标准)

XML 安全性

于 2009-01-18T21:36:47.927 回答