首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用BCrypt对密码进行客户端散列?

如何使用BCrypt对密码进行客户端散列?
EN

Security用户
提问于 2015-07-08 09:19:31
回答 5查看 55.1K关注 0票数 19

我正在将一个使用MD5哈希的旧应用程序迁移到Security,并对密码进行BCrypt编码。在将密码发送到网络之前,我希望在新用户创建页、更改密码页和登录页上对密码进行编码。

我知道HTTPS可以解决这个问题,但我仍然被要求在通过网络发送密码之前,按照我们的组织指南进行编码。

使用JavaScript对密码进行哈希处理的最佳解决方案是什么?

为了进一步解释,我使用JCryption API加密密码,所以通过网络传输的值是AES(SHA1(MD5(plain password))),现在我只想用Bcrypt替换MD5。其余的情况保持不变。这种方法对“中间攻击中的人”有效吗?

EN

回答 5

Security用户

回答已采纳

发布于 2015-07-09 00:44:38

bcrypt不适用于这种类型的客户端哈希

bcrypt的一个关键属性是,当使用相同的明文运行两次独立时,大多数实现将产生不同的哈希。这是由于使用了salt,它的目的是要查看两个不同的用户是否有相同的密码。

相反,每次登录表单都需要接收相同的数据。毕竟,您还会如何验证用户今天输入的密码是否与昨天输入的密码相同?

因此,您有一个算法,用于每次生成不同的数据,并将其输入到一个应用程序中,该应用程序每次都需要验证数据是相同的。这可能表明该算法没有按预期使用。

理想情况下,您应该使用bcrypt在服务器上散列密码。这就是bcrypt设计的目的:在明文不在内存的时候保护用户密码,这是目前为止最常见的状态(例如,如果实现正确,DB转储将只显示散列密码,而不是明文)。

我个人认为客户端散列也有一定的价值,因为它确实有助于防止攻击者嗅探流量(或具有服务器访问权限)。然而,我不知道如何使客户端哈希像服务器端bcrypt一样安全这就是为什么您仍然应该使用服务器端bcrypt。

如果必须使用bcrypt客户端,则使用静态盐

如果要将bcrypt用于登录表单的客户端散列,并且希望它是MD5的插入替代,则需要使用静态盐。特别是当您通过SHA1传递它时,因为这会破坏bcrypt盐以及散列数据本身。

当然,这打破了bcrypt的几个设计假设(比如总是使用随机盐)。

我个人建议使用用户名作为salt (因此很难判断两个不同的用户是否有相同的密码);然而,我不知道在这种情况下已经做过任何关于盐渍的研究。

AES (或任何对称密码)在这里也是无用的,

请记住,AES是一种对称算法,这意味着您需要相同的密钥来解密和加密数据。

这对你意味着什么?那么,您可能已经在JavaScript源代码中获得了您的加密密钥,它提供给任何访问您的登录页面的客户端。AES是一个对称密码,所以您的加密密钥(与解密密钥相同)应该保持私有。换句话说,您的私钥是众所周知的--它在这一点上实际上没有提供任何安全性。

您应该使用的是公钥加密,如PGP或HTTPS (技术上,HTTPS使用混合方法)。说真的,只要使用HTTPS,除非您的组织出于某种原因拒绝让您拥有SSL证书。请记住,PGP并不能真正防止主动的MITM攻击,但至少可以防止窃听。

票数 13
EN

Security用户

发布于 2015-07-08 12:33:36

我知道HTTPS可以解决这个问题,但我仍然被要求在通过网络发送密码之前,按照我们的组织指南进行编码。

这确实决定了你的处境。

基本上,您应该使用一个简单的解决方案(使用HTTPS),因为如果没有HTTPS,主动攻击者可以在身份验证步骤之后劫持连接,而不管您为密码使用了什么“编码”和散列(无论您与散列函数和加密进行了多少仪式切换,能够执行中间人攻击的攻击者都会成功)。然后,你也有一个指导方针,这既是愚蠢的,也是无法避免的。那么,你的问题是:你如何才能做好事情,并且仍然遵守“准则”?

请注意,该指南在几个层次上没有什么意义。SSL的缺乏不仅使协议容易被劫持,而且任何类型的“编码”对被动攻击者也没有任何好处。原因是,如果协议是“客户端显示‘编码’密码”,那么被动窃听者只需查看该“编码密码”并亲自发送--因此,这种编码实际上并不能以任何方式提高安全性。这只会让一些人感到更安全,因为他们把密码学理解为某种烧烤酱(“我们撒得越多,它就越好”)。

我建议你做以下几件事:

  1. 首先,尝试推销"HTTPS“体现‘编码’的想法。换句话说,通过在SSL隧道中发送密码,您已经遵守了准则,因为密码与其他数据一起被适当地编码(实际上是加密的)。
  2. 如果愚蠢的困扰更加严重,而且某些审计师(我们称他为Bob)仍然对您缺乏“编码”感到恼火,那么尝试在客户端应用一些可逆的编码。例如,在发送密码之前,应用Base64。这意味着,如果密码是“bob杂”,那么发送的内容(当然是在SSL中)将是"Ym9ic3Vja3M=",而Bob会更高兴,因为后者显然更安全。

这里最重要的一点是,由于需求没有意义,解决方案也不会有多大意义。

票数 48
EN

Security用户

发布于 2015-07-08 13:00:25

您没有身份验证

就没有安全性

为了进一步说明这一点,我使用JCryption API加密密码,所以在网络上传输的值是AES ( MD5 (普通密码)),现在我只想用Bcrypt代替MD5。其余的情况保持不变。这种方法甚至可以对抗“中间攻击中的人”。

不,不需要。我不能很强烈地表达这一点。现在,我可能无法说服您使用https (您可能甚至没有选择),但我希望我能够让您相信它是绝对不安全的,而且您对它的任何信念都是错误的。如果被迫在不使用TLS/SSL的情况下继续前进,您至少可以向每个参与的人非常清楚地表明,系统是脆弱的,应该被描述为“容易规避、感觉良好的安全性”。在当地星巴克运行MITM热点的脚本孩子可能会欺骗用户,窃取凭据或劫持会话,因此不需要复杂的技能或复杂的攻击。

如果通信通道不安全,您不应该期望您发送的代码是实际由客户端运行的代码。之所以它被称为https (安全http),而不仅仅是httpe (加密http),安全性不仅仅是加密。没有身份验证的加密通信是没有意义的。

有些事情需要考虑:

  • 没有https,用户如何知道他们在您的登录页面上?
  • 您怎么知道攻击者没有修改发送给用户的登录页面,以便在加密并发送给您之前向用户发送凭据的明文副本?
  • 您正试图加密密码的双重哈希,您将如何安全地传输加密密钥?

,如果除了加密

之外,我还进行了自己的自定义身份验证,该怎么办?

没那么简单。在不安全的通道上引导安全通道不是一个简单的问题。理论上,您可以构建一个自定义协议,该协议可以复制https的所有方面,包括协议协商、服务器身份验证、公钥基础设施、密钥交换、加密、消息完整性和撤销(而且我肯定会忘记更多)。一旦完成,它就会和TLS一样大而复杂。我们还假设它比任何TLS实现都有更少的缺陷,而且您可以在不到几年内完成它,您仍然会遇到一个几乎不可能的问题。您将如何将此客户端组件提供给客户端?“哦,当然要让客户安全地下载.呃等等”。如果通过一个不安全的通道引导安全通信看起来很容易,那么老实说,你看上去还不够深,那就是海龟。

现在让我说清楚,TLS有很多问题,CA系统也有很多问题。我当然不会假装它是完美的,但安全的沟通是如此之一的鸡和蛋问题,这是最好的解决办法。

客户端散列可以在https

上完成。

从您的措辞来看,您似乎认为这个问题是“客户端散列或服务器端散列在https之上”,但我希望您能看到这是一个谬误。无论如何对用户进行身份验证,都需要https。因此,如果您接受需要https,那么问题就变成“为什么或者什么时候使用客户端散列(超过https)而不是服务器端散列(超过https)?在大多数情况下是不会的。客户端散列更复杂,也不是更安全,但它确实有一个优势,那就是服务器对密码一无所知,而服务器端哈希则不是这样。在某些情况下,您希望您(服务器)是不可否认的。您不能丢失您没有的密钥,如果客户从未提供解密密钥,您也不能被迫解密客户的文件。因此,在某些情况下,它可能是强制性的要求,但它应该是项目设计的一部分,而不是任意的决定。如果您有关于如何处理零知识场景的具体问题,那么最好将其作为一个新的问题来处理。

票数 25
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/93395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档