如果您已经在使用 SSL,那么基本身份验证似乎是可行的方法,因为您可以在bcrypt
将密码存储在数据库中时使用密码执行,而 Digest 身份验证只允许md5
. 众所周知,在数据库被盗的情况下,md5
可以比bcrypt
.
我现在的问题是,鉴于 SSL 存在,而且您无法bcrypt
消化 auth 密码这一事实,我为什么还要在 Basic auth 上使用它?或者如果有 SSL,Basic auth 是以前的方式。
顺便说一句,这是用于 REST API 服务器
如果您已经在使用 SSL,那么基本身份验证似乎是可行的方法,因为您可以在bcrypt
将密码存储在数据库中时使用密码执行,而 Digest 身份验证只允许md5
. 众所周知,在数据库被盗的情况下,md5
可以比bcrypt
.
我现在的问题是,鉴于 SSL 存在,而且您无法bcrypt
消化 auth 密码这一事实,我为什么还要在 Basic auth 上使用它?或者如果有 SSL,Basic auth 是以前的方式。
顺便说一句,这是用于 REST API 服务器
如果您使用 SSL,那么选择不仅仅是在基本身份验证和摘要身份验证之间。如果您没有 SSL,则摘要式身份验证比基本身份验证更可取,尽管您仍然容易受到中间人攻击;尽管它使它们比基本身份验证更复杂。
但是,出于以下几个原因,我会避免使用基本身份验证:
出于这个原因,出于这些原因,我建议使用基于 cookie 的会话(通过 SSL),再次使用强哈希(例如 bcrypt)来存储密码。
你的假设是正确的。只要您正确使用 HTTPS,基本身份验证就是可行的方法。它允许您在 webapp 中实现所有加密和访问策略,而不是绑定到 HTTPD 的安全模型。
Digest 协议规范可以追溯到 1999年,当时 SSL 仍被视为一种过于昂贵而无法普遍使用的工具。RFC 以这一段开头,给出了上下文:
“HTTP/1.0”,包括基本访问认证方案的规范。该方案不被认为是一种安全的用户身份验证方法(除非与 SSL 5等外部安全系统结合使用),因为用户名和密码以明文形式通过网络传递。
这是整个文档中对 SSL 的唯一引用。这使事情变得清晰:Digest 旨在解决以明文形式发送密码的明显问题,就像 Basic在不与 SSL 一起使用时所做的那样。然而,我们知道,无论如何不使用 SSL 是一个大问题,因为自上个世纪以来,攻击者已经进步了一点:他们不再满足于被动窃听,他们实际上是劫持连接并实施中间人攻击。在这种情况下,再多的 Digest 也救不了你。
请注意,与 Basic 相比,Digest 的一个可能优势是即使服务器本身也不会泄露密码,以防服务器是敌对的 - 我的意思是您正在与攻击者控制的假服务器交谈。Digest 无法抵御中间人攻击,因此在这种情况下,您已经注定要失败,但只能在本地注定:攻击者可以看到您的数据并更改您的请求,但他不会知道您的密码,因此他将无法回来后来自己。有几点使这个优势非常小:
尽管使用假服务器的 Digest 不会向攻击者透露原始密码,但它仍然足以运行字典攻击,而且非常有效,因为它只有几个 MD5 哈希(甚至无法与 bcrypt 相比)。
固有的中间人攻击严重到足以要求进行适当的数据完整性检查,这意味着 SSL(请使用完整的服务器证书验证!)。如果 MitM 被击败,那么Digest 相对于 Basic 的优势就会像晨光中的露水一样蒸发。
另一方面,正如您所指出的,使用 Digest 意味着服务器必须自己存储密码(可能已加密,但以可逆的方式),这是 Digest 身份验证的一大缺点。
最好的办法是使用TLS 和 SRP,即 SSL/TLS 和基于密码的密钥交换,其中:
唯一的“次要”问题是 TLS+SRP 尚未得到广泛支持。GnuTLS可以做到。我们可以期待在未来得到更广泛的支持。同时,在 SSL 中使用基本身份验证,不要忘记彻底验证服务器的证书,并使用 bcrypt 在服务器端存储密码哈希。
摘要身份验证的密码存储实际上比您建议的要差。如果攻击者捕获了密码哈希,他们可以使用它自己执行摘要身份验证。不需要开裂。正如其他人所提到的,digest auth 在 SSL 普及之前就已经占有一席之地。
基于 SSL 的基本身份验证基本上没问题。但是,您可能需要考虑基于会话的解决方案。与其在每个请求中发送密码,不如发送一次以设置会话,然后在每个请求中发送会话 ID。鉴于密码是最秘密的东西,这可以最大限度地减少它的发送量。
另一位发帖人提到了 SRP,虽然 SRP 具有各种安全优势,但它并未得到广泛实施,因此对于大多数 Web 应用程序来说,它不是入门者。