背景:

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

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

宁静的身份验证 保护REST API / web服务的最佳实践 最好的SOAP/REST/RPC web api的例子?你为什么喜欢它们?他们有什么问题?

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

回到这个问题:

S3和OAuth都依赖于对请求URL和一些选定的头进行签名。它们都不为POST或PUT请求签名请求体。这难道不容易受到中间人攻击吗?中间人攻击会保留url和头部,并用攻击者想要的任何数据替换请求体。

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


当前回答

请记住,您的建议会使客户端难以与服务器通信。他们需要了解你的创新解决方案,并相应地加密数据,这个模型不太适合公共API(除非你是amazon\yahoo\谷歌..)。

无论如何,如果你必须加密主体内容,我建议你检查现有的标准和解决方案,如:

XML加密(W3C标准)

XML安全

其他回答

事实上,原始的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

前面的回答只提到了数据传输上下文中的SSL,实际上并没有涉及身份验证。

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

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

这些方案验证请求是由预期的人发送的。TLS (SSL)(不需要客户端身份验证)确保通过线路发送的数据保持不被篡改。它们是相互独立但又相互补充的问题。

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

请记住,您的建议会使客户端难以与服务器通信。他们需要了解你的创新解决方案,并相应地加密数据,这个模型不太适合公共API(除非你是amazon\yahoo\谷歌..)。

无论如何,如果你必须加密主体内容,我建议你检查现有的标准和解决方案,如:

XML加密(W3C标准)

XML安全

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

为了确保主体不被篡改,您将需要主体的签名,中间人攻击不太可能破坏这个签名,因为他们不知道生成签名的私钥。

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