对于网站,您的密码哈希是在客户端还是服务器端计算的?

对于网站,您的密码哈希是在客户端还是服务器端计算的?

我想知道密码输入是在客户端/网络浏览器端还是在服务器端本地“转换”。

我很确定是在服务器端,但在这种情况下,我担心的是:这意味着你正在将密码发送给第三方。事实上,密码将通过安全通道传输到服务器,但最终服务器可以对它做任何它想做的事情。自己计算哈希并将其发送到服务器将使身份验证过程更加安全。

如果本地方案不可能实现,您能否像我 5 岁一样解释为什么这是不可能的或者为什么这不是一个好主意?

答案1

我想知道密码输入是在客户端/网络浏览器端还是在服务器端本地“转换”。

通常(使用常规的基于表单的登录)一切都在服务器端完成。

但在这种情况下,我担心的是:这意味着你正在将密码发送给第三方。事实上,密码将通过安全通道传输到服务器,但最终服务器可以对它做任何它想做的事情

是的,确实可以。因此,我们警告不要重复使用密码。

自己计算哈希值并将其发送到服务器将使身份验证过程更加安全。

就其本身而言——不会。它会用一种风险换取另一种风险。

使用服务器端哈希,如果服务器的数据库泄露(比 TLS MITM 更常见),除非逐个破解,否则这些哈希几乎毫无用处。使用客户端哈希,攻击者可以像发送密码一样开始发送这些哈希!现在攻击者可以登录每个人的帐户,而不是一次性数据库泄露,他们可以保留这些哈希值并在数月或数年后使用它们登录。

(如果您让双方(首先是客户端,然后是服务器)对密码进行哈希处理,这仍然无法阻止恶意服务器存储客户端发送的哈希值并将它们重新发送到其他地方,就像密码一样。)

为了真正避免两个都问题,你需要的不仅仅是哈希;你需要一个稍微复杂一点的协议(例如某种不像“HTTP Digest”那样完全设计错误的质询/响应)。你会希望确保客户端发送的哈希值以后不能被重复使用(甚至在不同的站点上也不能),因为“重放攻击”是许多协议的问题。

例如,SCRAM 协议现在在 PostgreSQL 或 MongoDB 等非 Web 系统中很常见。然而,对于 Web 开发人员来说,所有这些都比仅仅编写 HTML 要复杂得多<form>——它们需要自定义 JavaScript 代码,并且通常需要与服务器进行多步交互。

似乎“既然我们无论如何都要添加 JavaScript”,那么整个网络正在转向不涉及密码的协议根本,例如使用公钥签名的 WebAuthn(有点像 SSH)。这并不一定意味着硬件加密狗和 2FA – “Windows Hello PIN” 是操作系统提供的 WebAuthn 的一个示例。

答案2

自己计算哈希并将其发送到服务器将使身份验证过程更加安全

不,接受哈希值而不是密码将使该过程安全性较差。这与保留纯文本密码相同:如果攻击者窃取了包含用户名和哈希值的服务器数据库,他们可以立即以任何用户身份登录!

哈希算法的整个目的是迫使攻击者逆转单向函数:从已知密码计算哈希值很简单,找到与给定哈希值匹配的密码却很难。当哈希值被盗时,字典中的单词等弱密码就会被破解,因为计算超过 100,000 个单词的哈希值很快。好的密码仍然很安全,因为要计算哈希值,您需要先猜出密码。

答案3

是的,当您在网站上输入密码时,它会以纯文本形式传输到服务器,然后服务器上的脚本可以对其进行任何操作,甚至以纯文本形式存储它。为了保护用户(大多数国家/地区的法律都要求网站这样做),他们会对密码进行哈希处理并仅存储哈希值,但这并不意味着这种情况总是会发生。

但即便如此,如果密码哈希被黑客入侵,如果真的需要并且有足够的时间(假设他们也获得了安全哈希),它最终可以被逆转为纯文本密码。

那么这意味着什么呢?在每个网站上都要使用唯一的密码。最好使用带有随机密码生成器的密码管理器,这样你就可以只记住一个密码,而忘记其他密码。有基于云的解决方案,也有本地解决方案,这取决于你对云计算的信任程度。

至于在本地计算哈希,从技术上讲,可以使用 javascript 来实现,但这会带来巨大的安全风险。创建密码哈希时,会使用最终基于该哈希的唯一哈希(安全哈希)。由于本地不知道此唯一哈希,因此无法解密密码。如果进行本地哈希,则服务器必须先向您发送秘密安全哈希才能获取哈希密码。然后黑客可以轻松解密任何哈希。

答案4

密码必须在服务器端进行哈希处理。如果您在服务器端的客户端上对密码进行哈希处理,并将哈希密码发送到服务器,那么哈希密码就是服务器用来验证您身份的东西,而“服务器用来验证您身份的东西”根据定义就是密码。因此根据定义,您发送给服务器的东西就是密码。如果您发送的东西是通过哈希处理生成的,那么您就是在无缘无故地做大量额外的工作。更重要的是,在服务器端用密码哈希值替换您的密码是无用的,因为它不会改变“如果有人入侵服务器,他们将拥有允许他们登录您帐户的数据”这一威胁向量。关键是服务器不拥有允许身份验证的信息;身份验证需要您的秘密信息(您的密码)和他们的秘密信息(您的密码哈希值)。

事实上,密码将通过安全通道传输到服务器,但最终服务器可以用它做任何它想做的事情。

嗯... 是吗?创建一个可以抵御“运行服务器的人在做不该做的事情”这种威胁的安全系统是不可能的。

自己计算哈希值并将其发送到服务器将使身份验证过程更加安全。

不,因为正如我所解释的那样,这意味着您发送的实际上是您的密码。也就是说,您发送的内容如果被拦截,将允许自由访问您的帐户。发送散列版本或发送未散列版本都无法解决该威胁向量。无论哪种方式,任何可以读取流量的人都可以冒充您。

为了解决这个问题,您需要进一步的安全协议,例如通过加密通道进行通信,并要求所有消息包含在会话之间变化的随机生成的盐。

相关内容