我正在构建一个需要用户登录的Web应用程序。所有通信均通过https进行。我正在使用bcrypt来哈希密码。

我正面临一个难题-我曾经认为,将密码哈希哈希到客户端(使用JavaScript),然后将其与哈希值进行比较会比较安全数据库服务器端。但是我不确定这比通过https发送纯文本密码然后在服务器端对其进行哈希处理更好。

我的理由是,如果攻击者可以拦截https流量(=读取纯文本密码),他还可以例如更改JavaScript,以便它将纯文本密码与散列密码一起发送-在此处可以拦截它。

禁止对客户端进行哈希处理的原因只是易于使用。如果我对客户端进行哈希处理,则需要使用两个单独的库进行哈希处理。这不是一个无法解决的问题,但是很麻烦。

使用客户端哈希可以安全吗?为什么?

我还应该使用质询响应吗?

UPDATE:我最感兴趣的是-这些技术(客户端哈希,请求响应) )在使用https的情况下会增加任何重大的安全性收益吗?如果是这样,为什么?

评论

stackoverflow.com/questions/3715920 / ...

感谢您提供的链接,但是尽管情况类似,但还是存在细微差别-我正在使用https。此外,我发现缺少答案的解释...如果可以读取页面,也可以对其进行修改,这意味着用户将以攻击者提供的形式输入密码。我将更新问题以更好地强调这一点。

另请参阅security.stackexchange.com/q/23006/2379

我个人认为所有客户端都应在发送密码之前对其加盐并对其进行哈希处理。当哈希版本也可以正常工作时,我看不出将我的纯文本密码提供给服务器的任何原因。我对这不是标准做法感到失望。 (当然,是的,密码也应该在服务器上加盐并进行哈希处理。)

在我大叫之后,有人问类似的问题:如何使用公共/私有密钥在网站中进行身份验证?

#1 楼

如果在客户端上进行哈希处理,则哈希处理后的密码将成为实际密码(哈希算法仅是将用户存储的助记符转换为实际密码的一种手段)。

这意味着您将在数据库中存储完整的“纯文本”密码(哈希),并且您将首先失去了哈希的所有优势。

如果您决定走这条路,不妨放弃任何哈希运算,而只是传输和存储用户的原始密码(顺便说一句,我不特别推荐)。

评论


您能详细说明为什么会这样吗? AFAIK使用散列密码的唯一优势是,在密码/散列密码被盗的情况下保护其他网站上的用户帐户-别无其他。如果是这样,那么散列的位置应该没有区别。我想念的散列还有其他优势吗?

–johndodo
2011年11月2日,12:35

实际上,存储加盐散列可以帮助您保护应用程序,使其免受攻击者通过读取身份验证数据存储内容而获得凭据的攻击。如果他无法从商店中推断出密码,则无法将其传递给服务器进行身份验证。

–妮可·卡利诺乌(Nicole Calinoiu)
2011年11月2日,13:06

Aaaah,这很有道理...攻击者掌握了散列密码,但是他无法在此系统上使用它,因为系统本身会对其进行散列-因此,他必须首先找到原始密码。好一个! :)

–johndodo
2011年11月2日,13:20

@johndodo“使用散列密码的唯一优势是在密码/散列密码被盗的情况下保护其他网站上的用户帐户”这不是唯一的原因。但这仍然是原因之一。

–好奇
2011年11月4日,0:52

@LuisCasilla不。答案的第一句话仍然适用-散列客户端密码不会给系统增加任何额外的安全性。

–augustar
17年2月8日在19:10

#2 楼

仅当您不以某种方式信任服务器并且不想向其显示“实际”密码(人类用户记住的密码)时,在客户端上进行散列才有意义。您为什么不希望将密码显示在该密码可以使用的网站上?因为您在其他地方重用了密码!现在通常很糟糕,但是有一个相对安全的版本,它包含在无数的浏览器扩展或书签中,例如一个或那个(我不保证其质量)。这些是人类用户记住“主密码”的工具,使用站点域名作为一种盐可以从中生成特定于站点的密码,以便两个不同的站点获得不同的密码。

尽管这种情况有意义,但使用服务器本身发送的Javascript却没有用。确实,散列密码客户端的要点是服务器可能是敌对的(例如,被攻击者颠覆),因此,该服务器发送的Javascript代码至少是可疑的。您不想在某些恶意Javascript中输入您的宝贵密码...


客户端哈希的另一种情况是慢哈希。根据定义,由于密码是弱密码,因此您希望阻止字典攻击。您假设坏人得到了服务器数据库的副本,并且将在自己的计算机上“尝试输入密码”(有关此问题的讨论,请参阅此博客文章)。为了降低攻击者的速度,您可以使用固有的慢速哈希处理(例如bcrypt),但这会使每个人(包括服务器)的处理速度变慢。为了帮助服务器,您可能需要分担客户端上的某些工作,因此至少要在客户端浏览器中运行的某些Javascript代码中完成部分工作...

不幸的是,JavaScript在这种工作上非常慢(通常比体面的C代码慢20到100倍),并且客户端系统将无法为哈希工作做出很大贡献。这个想法是合理的,但是必须等待更好的技术(不过,它会与Java客户端一起工作:对于一个不错的JVM,对于散列工作,优化的Java代码比优化的C代码慢大约2至4倍)。


总而言之,从服务器本身发送的Javascript代码进行客户端密码哈希处理并没有很好的案例。只需通过HTTPS隧道将密码“按原样”发送给服务器(登录页面,表单目标URL以及受密码保护的任何页面都应通过SSL进行服务,否则,与使用密码)。

#3 楼

我发现您的所有顾虑都不错,但我的建议是在服务器端进行操作。

用户总是有很大的机会将其终端保持解锁状态,从而可以进行操纵。并且;

另一种选择是在服务器端生成密码。那么您就不会发送明文密码。但是您仍然需要将密码传达给用户。而且由于大多数用户仍不使用加密电子邮件,因此我认为这种方法的安全性较低。

我已经看到了通过加密隧道将密码发送到手机的解决方案。但是我怀疑安全性要比SSL好。也许有人可以证明/反驳?

评论


“如果您的散列逻辑是客户端,则可以公开它。”所以呢?

–好奇
2011年11月4日,0:53

也许没什么大不了的。但是我更喜欢尽量少暴露。假设您拥有使用哈希密码的数据库。如果您知道哈希算法,则可以从常用密码列表中生成哈希列表,并将其匹配。

– rmorero
2011年11月4日,9:37

@rmorero:我倾向于不同意...首先,除了声纳或类似的东西外,您无法采取其他措施来防止用户将终端设备解锁。同样,隐藏的哈希算法是模糊的安全性。您必须决定什么是秘密,什么不是。隐藏非秘密事物通常会适得其反。

–johndodo
2011年11月7日在6:36



@johndodo是的,这些都是有效的观点。我上面的逻辑部分取决于错误的实现。不过,我要说的是,如果您依赖于默默无闻的安全措施,只会适得其反。我不建议这样做。

– rmorero
2011年11月7日在8:33

@rmorero:默默无闻的安全隐患并不是仅仅依靠它。正如我所看到的,三个主要问题是:a)花时间在它上面,而不是在实际的解决方案上,b)您可以使它成为现实。错误,实际上会使安全性更差; c)它使系统不那么透明,因此可能隐藏其他错误。换句话说,它增加了“雾气”-并且由于熟练的黑客可能在他的军械库中装有雾气灯,所以我希望阳光灿烂的日子面对他。 ;)

–johndodo
11年8月8日在20:18

#4 楼

正如所有其他答案所表明的那样,对服务器端进行哈希处理很重要,但是我想补充一下,除了对服务器端进行哈希处理之外,对客户端进行哈希处理也是一项不错的安全功能。

客户端散列在以下情况下具有优势:


服务器受到威胁时保护用户的密码。即如果客户端没有受到破坏,但服务器受到攻击,如果客户端对密码进行哈希处理,则服务器仍可以访问一个系统,但是您已经保护了用户的密码,如果用户在其他地方使用该密码,这很重要。 br />当用户认为自己正在登录一台服务器但实际上正在登录另一台服务器时(用户错误),它会保护用户的密码。例如,如果我有两个银行帐户,并且我不小心在错误的银行网站上键入了我的银行密码之一,如果该银行在客户端加密了该银行的密码,那么该银行将不知道我的另一银行的密码。我认为对客户端进行哈希处理是“礼貌”的事情,这样它们的纯文本密码就永远不会通过网络传输。

大多数情况下,它表示尊重用户的密码。用户共享的秘密可能不是您的软件独有的,因此,如果您尊重该秘密,则应尽一切努力保护它。

评论


我不会考虑启用/促进密码重用是有好处的。而且,由于使用了HTTPS,因此纯文本密码永远不会通过网络发送。

–augustar
17-2-8在19:02



@augurar我不会称其为启用或促进密码重用。用户是人类,人类会做一些不建议使用的事情,例如重用密码。我认为与防止用户选择弱密码相同。哈希密码客户端补偿了许多用户在您的网站上使用与他们的银行相同的密码这一事实。关于第二条语句,如果服务器受到威胁,则他们可以看到解密的HTTP请求和纯文本密码。

–塞缪尔
17年2月9日在3:10

每秒+1,客户端哈希是证明您不使用密码的唯一方法。 xkcd.com/792

–Agent_L
17年11月24日15:59

#5 楼

如果您位于HTTPS隧道中,则应从以太网监视中保护密码或哈希值。

在客户端,也许可以用会话ID来添加哈希值。
这可能是恶意Javascript更难模拟。

评论


值得注意的是,带有客户端哈希的固定+挑战盐可用于在非加密连接上实施安全密码机制(但显然会话令牌和其他后续交换并不安全)

–symcbean
11年2月2日在17:21

@symcbean“安全”是什么意思?

–好奇
2011年11月4日,0:54

我的意思是,密码传输机制不受窃听。

–symcbean
2011年11月7日,11:58

@kwolbert,您一直将评论发布为新答案,而不是评论。您是否可以将其作为注释附加到您要在上下文中阅读的含义,然后在此处删除答案?谢谢。

– Jeff Ferland♦
2012年8月29日19:07



@kwolbert欢迎使用IT安全!请仅使用发布答案按钮获取实际答案。您应该修改原始问题以添加其他信息。

–斯科特包
2012年8月29日19:31



#6 楼

散列密码的客户端将需要Javascript。有些人在其浏览器上禁用了Javascript。您必须处理这种情况。

我已经看到了论坛软件,该软件在客户端执行密码哈希处理,并在可能的情况下在登录时发送哈希,否则密码以纯文本形式发送。因此,无论哪种情况都可以使用。

如果您将使用https,则明确发送密码并不是主要问题。理想情况下,服务器应然后拒绝提供http中的页面,以免中间人受到攻击。原因是:攻击者可能会强制将您的连接从https降级到http,并开始嗅探流量(例如,使用SSL Strip之类的工具)。

评论


如果您想保留这些用户,则“必须处理此情况”。这是1%的人,如果您的网站不满,我认为可以说服90%的人打开它。

–吕克
20年1月7日在10:39



伙计,现在是2020年。如果有人禁用了浏览器上的所有Javascript,那么这就是他们的问题。

–埃克雷姆·丁塞尔(EkremDinçel)
20/09/22在14:46



2020年,很多人会使用广告拦截器或Noscript之类的插件在某些站点上选择性地拦截Javascript。您不能认为Javascript永远不会在客户端上起作用。但是请注意,这个问题已有8年的历史了,那时并不是每个网站都为登录页面(例如论坛)使用SSL。鉴于此,如今,对客户端的哈希密码进行哈希处理已变得毫无用处。无论如何,此修复很容易,如果禁用了Javascript,则在提交表单之前您无需对密码进行哈希处理。

–匿名
20-09-22在19:45

#7 楼

@Nicole Calinoiu的公认答案当然是正确的,但是一开始可能很难理解。

重点是应该在服务器上对密码进行哈希处理,以使恶意人员无法使用哈希他已经从服务器的数据库中窃取了访问您的帐户或数据的权限。

如前所述,如果您在客户端进行哈希并且后端支持该哈希,则哈希成为您的密码,并且如果哈希通过黑客被盗,则黑客具有密码。
/>
@Thomas Pornin的回答也提出了一个很好的观点,为什么您希望在客户端上散列密码,但是他在第一个故事中描述的内容只有在后端才能完成服务器的确支持处理散列密码(即,如果已经散列,则不对密码进行散列,但是有人试图支持类似的事情是极不可能的),在大多数情况下,我猜不是这样。他的第二个故事很好。

#8 楼

您可以同时执行这两种操作,并在客户端对其进行哈希处理,因此,如果攻击者可以通过https安全性获得保护,则他们将无法看到纯文本密码。然后在服务器上再次对其进行哈希处理,这样,如果攻击者获得了存储在服务器中的密码,他就不能仅将其发送到服务器并获得对密码的访问权限。

#9 楼

如果您的服务器将拥有多个可能的管理员,并且您不一定要信任所有人都不会获得ram dump,那么您应该真正对客户端进行哈希处理,以防止管理员窃取用户密码(尽管在其他网站上可能会重用)是一种不好的做法,用户会这样做,并将继续这样做。],然后对该哈希服务器端进行哈希处理,以使窃取表不会自动为攻击者提供网站本身的所谓纯文本密码。

只要使用安全哈希函数,就可以在双方使用相同的盐。

评论


如果您不信任管理员,那么您所遭受的伤害要大得多,而不必担心他们会偶尔从RAM中窃取用户密码。如果您有恶意的服务器管理员,则不能再保护用户密码,包括尝试至少在Web应用程序中对客户端进行哈希加密。

– Xander
17年1月20日在15:23



那么这个刚刚出现的cloudflare问题呢?我仍然说两端都是唯一的安全哈希。此外,如果您认为修改输出(使“尝试在客户端进行哈希”失败的必要步骤)就像偷看输入一样容易,那么您实际上从未见过物理计算机。

– codetaku
17-2-24在17:16



#10 楼

出于所有目的和目的,您只希望在客户端进行哈希处理。哈希背后的想法是防止除用户之外的任何人都不知道密码。因为任何好的站点都应该使用TLS,所以将哈希发送到服务器这一事实是无关紧要的(请注意,即使担心发送纯文本密码也同样糟糕)。

最后列出的答案似乎没有意识到,如果服务器遭到破坏,则服务器上的每个个人密码都会被泄露,因为密码是以纯文本形式发送给它的。

评论


仅以纯文本形式发送密码并不意味着它以纯文本形式存储。如果攻击者破坏了服务器的访问能力,他们可能会修改发送给客户端的代码,以获取用户密码。

–马修
16年4月7日在19:22

如果服务器曾经遭到破坏,则服务器发送给客户端以进行客户端哈希处理的代码也将受到威胁,因此这实际上是对恶意服务器的无用控制。

– Xander
16-4-7在21:26

@Matthew这对用户是可见的。服务器端捕获不是。 (也适用于Xander,但我不能同时ping两个。)如果有足够大的银行进行客户端哈希,那么如果人们开始监视javascript文件(也许银行自己是从外部访问的话),我也不会感到惊讶。 IP)或自弹出窗口检查自上次访问以来所做的更改。

–吕克
20年1月7日在10:49