代码之家  ›  专栏  ›  技术社区  ›  Jader Dias

在将密码发送到服务器端之前,是否应该对其进行哈希处理?

  •  86
  • Jader Dias  · 技术社区  · 14 年前

    我注意到大多数站点都会将密码以明文形式通过HTTPS发送到服务器。如果我把密码的散列信息发送给服务器,有什么好处吗?会更安全吗?

    11 回复  |  直到 14 年前
        1
  •  161
  •   Thomas Tempelmann    5 年前

    OP从未提及通过仅HTTP的HTTPS以明文形式发送密码,然而许多人似乎出于某种原因对通过HTTP发送密码的问题作出了回应。也就是说:

    我认为密码永远不应该以明文形式保留(更不用说传输了)。这意味着没有保存在磁盘上,甚至内存中。

    在这里回应的人似乎认为HTTPS是一颗银弹,而事实并非如此。不过,它确实非常有用,应该在任何经过身份验证的会话中使用。

    所需要的只是一种基于用户选择的原始文本生成(并可靠地重新生成)身份验证“密钥”的可靠方法。在一个理想的世界里,这篇文章应该通过使用不可逆盐对其进行散列来立即生成一个“键”。此salt对于正在生成的用户凭据应该是唯一的。这个“密钥”将是您的系统使用的密码。这样,如果您的系统在将来遭到破坏,这些凭证将只对您自己的组织有用,而在其他任何地方,用户都懒得使用相同的密码。

    所以我们有钥匙。现在我们需要清除客户端设备上的任何密码痕迹。

    下一步我们需要拿到你系统的钥匙。你不应该在“透明”的情况下传送钥匙或密码。甚至不能通过HTTPS。HTTPS不是不可穿透的。事实上,许多组织可以成为受信任的MITM—不是从攻击的角度来看,而是对流量执行检查以实现自己的安全策略。这削弱了HTTPS,而且这不是它发生的唯一方式(例如重定向到HTTPMITM攻击)。千万不要以为它是安全的。

    为了解决这个问题,我们用一个一次性的nonce来散列密钥。每次向系统提交密钥时,此nonce都是唯一的—即使是在同一会话期间,如果需要多次发送相同的凭据,也可以使用此nonce。一旦这个nonce到达您自己的系统中,您就可以反转它来恢复身份验证密钥,并对请求进行身份验证。

    在这一点上,在它永久存储在您自己的系统中之前,我将对它进行最后一次不可逆转的散列。这样,您就可以与合作伙伴组织共享凭证的盐,以实现SSO等目的,同时能够证明您自己的组织无法模拟用户。这种方法最好的一点是,在没有用户授权的情况下,您永远不会共享用户生成的任何内容。

    做更多的研究,因为它有更多的,甚至比我已经透露,但如果你想提供真正的安全,你的用户,我认为这种方法是目前最完整的回应这里。

    热释光;博士:

    使用HTTPS。 安全地散列密码,不可逆地,每个密码有一个唯一的salt。在客户端执行此操作-不要传输其实际密码。将用户的原始密码传输到服务器永远不会是“OK”或“Fine”。清除原始密码的任何痕迹。 使用 nonce

        2
  •  26
  •   Kiersten Arnold    14 年前

    因为它是通过HTTPS发送的,所以发送密码时不需要散列(通过HTTPS它不是明文)。此外,如果您的应用程序依赖于HTTPS来保证其内容的安全,那么在通过HTTPS发送密码之前对密码进行散列是没有用的(即,如果攻击者可以解除有线数据的加密,那么您无论如何都会失败)

        3
  •  18
  •   Hello World    10 年前

    不,事实上这是一个弱点。如果攻击者能够从数据库中获取哈希,那么他可以使用它进行身份验证,而无需破解它。在任何情况下,用户或攻击者都不能获取哈希密码。

    散列密码的全部目的是增加一个额外的安全层。如果攻击者能够使用SQL注入或不安全的备份从数据库中获取哈希和salt,那么他必须通过暴力强制来查找纯文本。 John The Ripper 通常用于打破咸密码散列。

    A9-Insufficient Transport Layer Protection

    编辑: 如果在实现中计算 sha256(client_salt+plain_text_password) 然后在服务器端计算另一个哈希 sha256(server_salt+client_hash) 那么这不是一个严重的漏洞。但是,它仍然容易被窃听和重播请求。因此,这仍然是一个明确的违反黄蜂A9。但是,这仍然使用消息摘要作为安全层。

    我见过的最接近于客户端替代https的东西是 diffie-hellman in key exchange in javascript . 然而,这确实阻止了主动的MITM攻击,因此直到技术上违反了OWASP A9。代码的作者同意,这并不是HTTPS的完全替代品,但是它总比没有好,也比客户端哈希系统好。

        4
  •  9
  •   Paul Keister    14 年前

        5
  •  7
  •   Victor Zimmer    9 年前

    明文密码show never(甚至在使用HTTPS时)离开客户端。它应该在离开客户机之前进行不可逆转的散列,因为服务器不需要知道实际的密码。

    散列然后传输解决了在多个位置使用相同密码的懒惰用户的安全问题(我知道我知道)。但是,这并不能保护您的应用程序,因为黑客可以访问数据库(或以任何其他方式获得哈希),因为黑客可以传输哈希并让服务器接受它。

    我在创建的基于套接字的web应用程序中解决这个问题的方法是,在连接到客户端时,服务器生成一个salt(散列之前要添加的随机字符串),并将其存储在sockets变量中,然后将这个散列传输到客户端。客户机获取用户密码,对其进行哈希运算,从服务器添加salt并对整个内容进行哈希运算,然后将其传输到服务器。然后它被发送到服务器,服务器将这个散列与散列(DB+salt中的散列)进行比较。据我所知,这是一个很好的方法,但公平地说,我没有读过很多关于这个话题的书,如果我对任何事情有错误,我希望得到纠正:)

        6
  •  3
  •   vlad b.    14 年前

    维基百科:

    HTTP摘要访问身份验证是web服务器可以用来与web用户协商凭据(使用HTTP协议)的约定方法之一。摘要认证旨在取代基本访问认证的未加密使用,允许安全地建立用户身份,而无需通过网络发送明文密码。摘要身份验证基本上是MD5加密哈希的一个应用程序,它使用nonce值来防止密码分析。

    链接: http://en.wikipedia.org/wiki/Digest_access_authentication

    http://siege.org/phpmyid.php

    .. 或者您可以从以下位置的php auth示例开始 http://php.net/manual/en/features.http-auth.php

    http://www.faqs.org/rfcs/rfc2617

    从我的测试来看,所有的现代浏览器都支持它。。。

        7
  •  3
  •   Bill the Lizard    14 年前

    如果你想用HTTP上的散列密码替换HTTPS上的明文密码,那你就自找麻烦了。HTTPS在打开通信通道时生成一个随机的、共享的事务密钥。这是很难破解的,因为您几乎仅限于强制使用用于(相对)短期事务的共享密钥。然而,你的散列可以只是嗅探,离线,并在彩虹表中查找,或只是暴力强迫了很长一段时间。

        8
  •  3
  •   pixelpax    7 年前

    免责声明:我绝对不是一个安全专家——我和 其他人会批评我的立场过于谨慎或改进,我会从中吸取教训。话虽如此,我只想强调的是,当它离开你的客户机时,哈希并不意味着你在把它放入数据库之前不需要在后端进行哈希运算。

    两者都做是因为:

    1. 在ride over上进行散列有助于覆盖传输漏洞,如果SSL连接被破坏,他们仍然看不到原始密码。就能够冒充授权用户而言,这并不重要,但它可以保护您的用户,使他们的密码不会在与电子邮件的关联中被读取。大多数人不遵循最佳实践,对他们的许多帐户使用相同的密码,因此这对访问者来说是一个严重的漏洞。

    2. 如果有人能够以某种方式从数据库中读取密码(这种情况确实发生,比如SQL注入),他们仍然无法通过我的API执行模拟用户的特权操作。这是因为散列不对称;即使他们知道数据库中存储的散列,他们也不知道用于创建散列的原始密钥,而这正是auth中间件用来进行身份验证的。这也是为什么你应该总是盐你的散列存储。

    当然,如果他们能自由地从你的数据库中读取他们想要的内容,他们可能会造成很多其他的伤害。

    我只想在此强调,如果您决定在离开客户机之前对密钥进行哈希处理,这是不够的——在我看来,后端哈希处理更为重要,这就是原因:如果有人正在拦截来自您客户机的流量,那么他们将看到 password

        9
  •  2
  •   jac    14 年前

    如果连接到https服务器,则服务器和浏览器之间的数据流应加密。数据在发送之前和接收之后都是纯文本。 Wikipedia article

        10
  •  1
  •   Tom Kip    8 年前

    SSL/TLS不是正在取代nonce吗?我不认为这有什么附加价值,因为SSL/TLS还可以防止重放攻击。

    裁判。 https://en.wikipedia.org/wiki/Cryptographic_nonce

        11
  •  1
  •   phatfingers    5 年前

    是否有优势,以及是否更安全(或更少)实际上取决于实现。可以说这有一些好处,但是如果你实现得不好,你肯定可以创建一个比传递明文密码更不安全的解决方案。

    这可以从两种攻击的角度来看待——一种是访问网络流量,另一种是访问数据库。

    如果攻击者可以截获明文版本的网络流量,那么查看密码哈希比查看明文密码更安全。尽管攻击者仍然可以使用该散列登录到您的服务器,但它需要对该散列进行暴力破解(有时是预先计算的),以确定在其他系统上可能有用的密码。人们应该在不同的系统上使用不同的密码,但通常不会。

    如果攻击者获得了对数据库的访问权,可能是通过备份的副本,那么您需要确保只有这些知识才能登录。例如,如果您存储了一个以登录名为 hash(login_name+password) 这就是实现的关键所在。

    要记住的概念:

    • 在进行身份验证时,始终在服务器端对作为密码从客户端传递的任何值进行哈希处理(即使已经对其进行哈希处理),并将其与存储在数据库中的预哈希值进行比较。这可能需要存储原始密码的双哈希版本。
    • 创建哈希时,请考虑向哈希中添加服务器/集群唯一的salt以及行唯一的salt,以防止与查找表中任何预先计算的哈希匹配。
        12
  •  1
  •   Dan    3 年前

    例如,

    1. 服务器生成 随机字符串 并生成一个 发送给用户。
    2. 用户根据自己的密码计算一个哈希值,并将此哈希值用作 是JS中的一个实现)并将其发送回您。
    3. 您自己使用存储在服务器上的散列,也可以对其进行加密 带有蓝色条纹的随机字符串。
    4. 比较一下。

    攻击者必须使用随机源和密文攻击bluefish密钥。这项任务不容易。

        13
  •  0
  •   Carter Medlin    14 年前

    实际上,散列密码并通过非加密通道发送它会更不安全。您将在客户机上公开哈希算法。黑客可以嗅出密码的散列,然后用它来入侵。

    通过使用HTTPS,可以防止黑客从单一来源获取密码,因为HTTPS使用两个通道,都是加密的。