REST身份验证方案的安全性


228

背景:

我正在为REST Web服务设计身份验证方案。这并不是“真正”需要安全的(它更多是一个个人项目),但我想使其与练习/学习经验一样安全。我不想使用SSL,因为我不想麻烦,而在大多数情况下,它不需要设置它。

这些SO问题对于帮助我入门特别有用:

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

要解决这个问题:

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

似乎我可以通过在请求的字符串中包含请求主体的哈希值来防止这种情况发生。这样安全吗?


6
Amazon S3可以在标题字符串中包含Content-MD5,以防止您描述的MITM攻击。
laz

8
MD5是一个非常弱的哈希函数,并且多年来一直不鼓励使用它:en.wikipedia.org/wiki/MD5。现在使用SHA2。MD5是患有身份危机的猪的口红。
亨里克(Henrik)2012年

6
Startcom提供免费的SSL证书,这些证书不会在主要浏览器中引发证书警告
柏拉图

5
@SeanKAnderson(rant:我发现当人们受到间谍机构的围攻时,人们谈论99.99999%s真是荒谬的,这些机构已经在2008年自动进行了许多攻击-这是处理真实问题的一种奇怪方法- “纳阿,不会有问题;对我奶奶来说,这是无法破解的”
亨里克

2
@Plato我建议这些天让LetsEncrypt获得免费的SSL证书
Google穿梭巴士

Answers:


168

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

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

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

这些方案验证请求是由预期的人发送的。TLS(SSL)(无客户端身份验证)可确保通过网络发送的数据保持不受干扰。它们是相互独立的,但又是互补的。

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


16
究竟。就您的API而言,SSL唯一可以验证的是它正在处理的调用在途中没有被弄乱。API仍然不知道是谁在与之交谈,也不知道他们是否应该具有访问权限。
蒂姆·高铁耶

1
好答案。我还建议在看看这些优秀的资源.. owasp.org/index.php/Web_Service_Security_Cheat_Sheetowasp.org/index.php/REST_Security_Cheat_Sheet(草案)
dodgy_coder

2
这只是一个很小的要点,但是使用SSL还具有防止窃听和中间人攻击的其他好处。
dodgy_coder

@Les Hazlewood您能解释一下Https上的HTTP Basic身份验证如何帮助确定服务器知道与谁通话吗?
春天

@Les Hazlewood在这里我问了一个问题;TNX stackoverflow.com/questions/14043397/...

60

REST表示符合Web标准,而Web上“安全”传输的标准是SSL。其他任何事情都会变得很时髦,并且需要为客户端进行额外的部署工作,这将必须具有可用的加密库。

原则上,一旦您提交SSL,实际上就不需要花哨的时间了。您可以再次使用Web标准并使用HTTP Basic身份验证(与每个请求一起发送的用户名和秘密令牌),因为它比精心设计的签名协议要简单得多,并且在安全连接的情况下仍然有效。您只需要确保密码永远不会覆盖纯文本即可。因此,如果曾经通过纯文本连接收到密码,则您甚至可能会禁用密码并向开发人员发送邮件。您还应该确保凭据在收到后不会记录在任何地方,就像您不会记录常规密码一样。

HTTP摘要是一种更安全的方法,因为它可以防止传递秘密令牌。而是服务器可以在另一端验证的哈希值。如果您已采取上述预防措施,对于不太敏感的应用程序可能会显得过高。毕竟,用户的密码已经在他们登录时以纯文本格式传输(除非您在浏览器中进行了一些精美的JavaScript加密),并且同样在每次请求时都存储了他们的cookie。

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

使用令牌的主要原因是,如果令牌被泄露,则可以将其替换;而如果密码被泄露,则所有者可以登录开发人员的帐户并对其进行任何操作。令牌的另一个优点是您可以向同一开发人员发行多个令牌。也许是因为他们拥有多个应用程序,或者是因为他们想要具有不同访问级别的令牌。

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


3
我认为您可以以每年30美元的价格获得GoDaddy ssl证书。我很震惊地看到Verisign SSL证书要花多少钱(每年600美元,如果我没记错的话,还可以吗?)但是GoDaddy选项是完全可行的。
Brian Armstrong 2010年

19
除非您使用SSL / TLS双向身份验证,并且用户/客户端使用的证书受服务器信任,否则您尚未向服务器/应用程序对用户进行身份验证。您将需要做更多的事情来向服务器/应用程序验证用户身份。
Pauld 2011年

5
瑞恩:SSL加密,这些天需要相比,你会用什么来生成像Django的或者Rails等一个Web应用程序框架响应的处理能力非常微小的量
卡梅隆沃尔什

4
startcom的证书是免费的并且得到广泛认可。cacert.org是一种知名度较低的开放式替代方案
Dima Tisnek 2012年

17
这没有解决有关身份验证的问题。
山姆·斯坦斯比

8

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


2
自签名证书是免费的,但是AFAIK您仍然需要一个静态IP。
dF。

8
@dF不需要静态IP,除非某些商业许可证书需要付费。
克里斯·马里西奇

如果您可以控制两端(客户端和服务器)的证书存储,那么这可能是一个可行的选择,但是...证书管理和分发在生产中可能比在开发环境中复杂得多。在提交替代方案之前,请务必先了解其复杂性。
Aled

5

如果您需要将主体的哈希值作为URL中的参数之一,并且该URL是通过私钥进行签名的,那么中间人攻击将只能用生成内容的主体替换主体。相同的哈希。至少现在至少可以轻松使用MD5哈希值,并且当SHA-1损坏时,您就会明白了。

为了保护主体免遭篡改,您需要提供主体的签名,而中间人攻击不太可能破坏该签名,因为他们不知道生成签名的私钥。


9
提出一个将产生与有效内容相同的md5哈希值的字符串可能比它本来应该容易得多,但是提出一个散列为相同值的有效内容的邪恶版本仍然非常困难。这就是为什么md5不再用于密码哈希,而仍用于验证下载的原因。
蒂姆·高铁耶


1

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

无论如何,如果您必须对身体内容进行加密,我建议您检查一下现有的标准和解决方案,例如:

XML加密(W3C标准)

XML安全性

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.