【问题标题】:How to send password securely via HTTP using Javascript in absence of HTTPS?如何在没有 HTTPS 的情况下使用 Javascript 通过 HTTP 安全地发送密码?
【发布时间】:2010-01-05 00:07:29
【问题描述】:

所有开发人员都面临的非常基本的问题:每当用户提交表单时,密码都是通过网络发送的,并且必须受到保护。我开发的网站没有 HTTPS。所有者既不想购买 SSL 证书,也对自签名证书不感兴趣。所以我想在提交表单时使用 Javascript 保护通过 HTTP 发送的密码。

致急于投票的人:How to send password securely over HTTP? 没有给出任何明智的解决方案,我处于另一种情况。

如果我使用 MD5,可以反转该密码字符串。随机数/HMAC 呢?有什么可用的Javascript库吗?或者你有什么建议/提示要解决吗?提前致谢!

【问题讨论】:

    标签: security http hash password-protection hmac


    【解决方案1】:

    没有办法安全地发送密码用户可以在没有 SSL 的情况下验证

    当然,您可以编写一些 JavaScript,通过散列或公钥加密来确保密码安全,以便通过网络传输。但是用户如何确保 JavaScript 本身在到达他们之前没有被中间人篡改,将密码发送给攻击者而不是站点,甚至只是危及安全算法?唯一的方法是让他们成为专家级的程序员,让他们检查你的页面和脚本的每一行,以确保在输入密码之前它是洁净的。这不是一个现实的场景。

    如果您希望密码免受中间人攻击,您必须购买 SSL 证书。没有其他办法。习惯就好。

    如果我使用 MD5,可以反转该密码字符串。

    不...至少不是微不足道的。虽然 MD5 对其进行了攻击,但它是一种散列算法,因此是不可逆转的。你将不得不暴力破解它。

    但同样,中间人攻击者不需要查看您的 MD5。他可以简单地破坏您发送给用户的 JavaScript 来制作 MD5。

    【讨论】:

    • 优秀的帖子。我尝试使用 JavaScript 进行安全密码输入,但由于这些确切原因,我意识到这是不可能的。我希望我能先读到这篇文章。
    • > 您忘记了预先计算的 MD5 密码哈希表,这意味着“暴力破解”很可能既快速又简单。
    • EricLaw:你指的是彩虹桌?它们只包含不超过一定长度的文本哈希。
    • 无论如何,在选择哈希函数之前,每个人都应该检查他们决定的那个的最新细节:valerieaurora.org/hash.html,具体来说,MD5、SHA0、SHA1都被认为是死的。仅使用 SHA-2 及更高版本。
    • 正如 Jerry Stuckle 在那个帖子中所说,它仍然没有用。在顶部添加更多安全性没有任何区别;在开始输入凭据之前,用户仍需阅读并验证发送给他们的客户端脚本是否符合犹太教规。那不会发生。您需要某种秘密来引导安全连接; SSL 以共享 CA 的形式提供。如果没有它,您可能会与任何伪装成目标网站的随机活跃的 MitM 黑客交谈。密码散列登录方案虽然出于其他原因可能有用,但只能击败被动 MitM。
    【解决方案2】:

    这里的解决方案是根本不发送密码。使用挑战/响应。

    在原始形式中包含一大块随机文本和一个键。根据服务器上的密钥将原始随机文本存储在会话中。当客户端提交表单时,使用 JS 将随机文本和密码一起散列。然后将用户名、密钥和散列随机文本发送到服务器。不要发送密码。在服务器上,使用密钥查找原始随机文本,对存储的密码执行相同的散列操作。如果服务器哈希值与客户端哈希值匹配,那么您就知道客户端输入了正确的密码,而无需将密码发送到服务器。

    无论密码是否正确,都会使密钥和随机文本过期,以便一次性使用。

    【讨论】:

    • 您仍然需要将密码至少发送一次到服务器以存储在数据库中。在这种情况下你会怎么做?
    • @ZloySmiertniy,当您需要通过电子邮件提供密码重置时,最好发送重置密码的一次性链接,而不是发送实际密码本身。这可以防止密码通过电子邮件传输并稍后存储在电子邮件中的安全问题。
    • 如果我是“中间人”,我会抓住那个随机散列字符串,并用它来进行身份验证,所以你在浏览器中做了什么并不重要。通过在客户端和服务器上进行相同的哈希处理,您刚刚向我展示了如何在服务器端进行身份验证、使用的算法、通过次数等。
    • 这不足以抵御 MITM,该 MITM 会修改服务器返回的 JS 代码以捕获密码字段内容(或通过在密码输入上注册侦听器的跨站点攻击) .为了防止这种情况,您需要子资源完整性来声明您的 javascript 和 CSP。
    • @xryl669 是的,非常好。这个问题和答案已有 8 年历史,今天我不建议任何人在没有 https 的情况下运行网站,因为现在它比 8 年前更常见、更便宜。
    【解决方案3】:

    如果您真的想深入了解这一点,请查看Diffie-Hellman key exchange,该Diffie-Hellman key exchange 旨在“允许事先不知情的两方通过不安全的通信通道共同建立共享密钥”

    虽然我不是密码学专家,所以我不完全知道如果攻击者同时拥有客户端(JavaScript 源代码)和传输机制(数据包嗅探器)是否真的安全

    【讨论】:

    • 如果你做对了它是安全的......但是做对了却非常困难。 SSL 是一种方式,更少的工作。
    【解决方案4】:

    您可以在发送前使用 javascript RSA 实现对密码进行加密。 (这里是RSA In Javascript 的示例。)

    但我相信这个和使用哈希函数都会受到replay attacks 的攻击。所以,小心点。

    【讨论】:

      【解决方案5】:

      很遗憾,没有办法确保未加密请求的安全性。任何有权访问您的 javascript 的人都可以对其进行逆向工程/篡改,任何拥有数据包嗅探器的人都可以查看未加密的流量。这两个事实共同意味着:

      没有 SSL?没有安全保障。

      【讨论】:

      • 我还认为 SSL 与没有安全性一样糟糕,因为您可以为不拥有的域购买 CA 签名证书。尽管它变得越来越少见,但我确信我可以找到一个 CA 可以拿走我的钱并签署证书。有了这个 - 你怎么知道你去的大通网站实际上是大通的网站而不是攻击者?他们都可以拥有有效的签名证书。
      • 大的不会这样做,而且很多其他的在浏览器中的支持很差。情况并不完美,但我不会称其为“糟糕”,因为没有安全。
      • 错了。 SSL 只是一个协议,SSL 本身没有安全性。安全性来自 Diffie Helman/Key 派生,您也可以在 Javascript 中实现它。您需要在客户端和服务器之间至少进行 3 步(2 次交换)以确保 Javascript 代码正确(就像 SSL 一样)。一切都在服务器端检查。
      【解决方案6】:

      您拥有的任何传输都将是明确的;也就是说,如果没有 SSL,您的关键信息将被暴露。值得与网站所有者讨论这一点。换句话说,最好采取必要的措施来加强您的数据传输,而 SSL 是您可以采取的基本、廉价的步骤之一。

      【讨论】:

        【解决方案7】:

        我认为这里的问题不在于技术,而在于您如何解释 SSL 的重要性。为他们提供可靠的阅读材料,我相信网上有很多。

        【讨论】:

          【解决方案8】:

          该解决方案要求客户端能够使用客户端服务器知道的秘密加密密钥来加密密码。

          SSL 通过要求服务器和客户端 Web 浏览器拥有自己的非对称公钥/私钥对来实现这一点,它们使用它们来加密和传输它们之间的随机会话密钥。然后对话的其余部分使用该安全会话密钥。

          因此,您要问的是如何解决与 SSL 相同的问题,而没有客户端和服务器知道的密钥的好处。我不是专家,但看起来这不可能,或者至少不容易。

          【讨论】:

          • 不,它没有。只有一个终端需要证书。客户端不生成会话密钥;不加密;并且不发送。它通过密钥协议协议进行协商。
          • @EJP - 是的,服务器创建并加密会话密钥。但是,如果客户端没有自己的(非对称)加密密钥,如何执行密钥协商协议呢?
          • 原理是:服务器发送它的身份和一个伪随机值(预主密钥),该值来自他知道的秘密。一旦客户端验证了服务器的身份(在证书中),它就会生成一个随机密钥对。对于私有部分,它使用预主密钥并将其转换并发送回。然后他们都派生了一个共同的密钥,而他们都没有透露他们的私钥,因此 MITM 无法找到会话密钥。
          • @xryl669 - 对,所以服务器和客户端都有自己的公钥/私钥对,它们用于派生只有他们知道的会话密钥。 OP 询问如何在没有密钥对的情况下执行此操作,据我所知,这无法安全完成。
          • 重要的是客户端为每个会话生成一个新的密钥对(因此客户端事先不需要一个)。但是,服务器始终使用相同的密钥对。 SSL 只是添加了一个签名链,以确保服务器是来自某些已知“黄金”根的正确服务器。
          【解决方案9】:

          如果您无权访问 SSL,MD5 应该足以防止意外发现密码(例如在网络日志文件或其他内容中)。其他任何事情都是浪费时间。只需确保该应用不会提供对敏感信息(即信用卡号、病史等)的访问权限。

          就像其他评论者所建议的那样,严重的攻击者将能够破坏页面上的任何类型的安全性。即使 SSL 也是一个小障碍,因为大多数用户使用易于猜测的密码,在任何地方重复使用相同的密码,会将密码提供给任何询问的人,或者可能被复制的页面或“技术”欺骗而放弃密码支持”的电话。

          【讨论】:

            【解决方案10】:

            -- 英文-- 我想在某事上,但我不知道它是否真的很安全。如果你可以把你的表单放在一个 php 文件中,那么你可以创建一个算法来创建一个基于时间或其他东西的字符串,然后把这个字符串放在你的 html 中。

            当用户在密码输入框输入密码时,调试时看不到用户输入的值,所以在通过post或get发送信息之前,可以使用密码用户作为提示加密之前生成的加密字符串,然后,只是将用户输入的密码发送给它。

            这样,攻击者就没有js代码的全部了,所以他们需要发现你创建的算法来解密它。

            这只是一个想法,所以如果你能告诉我这怎么可能不安全,我将不胜感激。

            -- 西班牙语-- Se me acaba de ocurrir algo que puede servir,pero no se si realmente sea algo seguro。 Por medio de php puedes Generar un algoritmo que Cree un string en base al timestamp o algo más, y después colocar esta cadena en el html。

            Note que cuando alguien escribe una contraseña en un campo input tipo password, con un debug no se puede ver el valor que tecleo el usuario (no se si exista manera pero no quiseinvestigar más), asi que podemos utilizar la contraseña que el usuario escribió como palabra clave para encriptar la cadena de texto que previamente habiamos Generado con php, por medio de un algoritmo en JS. Sería algo así como encriptar lo encriptado。 Posteriormente lo que estariamos enviado no sería la contraseña tecleada, si no esta última cadena resultante。

            Buscando un contra, lo único que se me ocurra es que el atacantetendra que dedicarle mucho tiempo para tratar de encontrar el agoritmo que creamos por medio de php y poder decriptar la cadena final, o tendra que hackear el servidor para acceder al php y obtener el algoritmo.

            Esto es solo una idea, por lo que si pueden decirme como esto puede no ser seguro, se los agradecería。

            【讨论】:

              【解决方案11】:

              如前所述,这些都不能防止服务器 欺骗,因为这需要信任客户端 Javascript 的能力。但是,如果我们确定服务器不会被欺骗(签名证书、哈希签名不受长度扩展影响等),但 不是 连接不受窃听者的影响,这就是我的方法实施它。

              我认为最安全的方法是,存储 g^H(password) 而不是存储 H(password),其中 H 是您选择的哈希函数,存储 g^H(password) 即使用密码作为 Diffie-Hellman 密钥交换的私钥。 (你也应该为不同的用户使用一个随机的 g ——它成为你的盐。)然后为了验证,你生成一个随机数 b,发送用户 g^b,并计算 (g^H(password ))^b。用户不需要知道 g——他们只需要计算 (g^b)^H(password) = (g^H(password))^b。现在您有了一个双方都知道iff用户输入正确密码的数字,并且基于知道正确数字构造一个挑战-响应零知识证明是微不足道的,而用作随机数的随机数服务器的“私钥”使该方法免受重放攻击。

              【讨论】:

              • 无论客户能做什么,MITM 也能做。您说的是“签名证书”,与已安装的 SSL 证书有什么区别? “服务器不能被欺骗”是什么意思,是否意味着通信不能改变,只能听?
              • 我的意思是,基本上,除非服务器的身份已经向客户端验证,否则这种解决方案是无用的,这通常意味着当今世界的 SSL 证书和端到端加密。是的,我的意思是可以窃听但不能冒充服务器或更改其输出不可察觉的情况,例如服务器的公钥是已知的(由受信任的来源验证),它使用用其私钥加密的 SHA3 哈希对所有消息进行签名。
              • 我是否理解正确,您的意思是只要内容安全交付,这种机制对于非 SSL api 层来说是有点安全的?不是我提倡,只是好奇。我实际上想在我们的内部堆栈中实现一些像这样的东西。我们有一个单一的身份验证服务器,我们希望我们所有的应用程序都可以共享它。我们的各个应用程序不需要知道密码,因此这个质询响应概念可能会满足这一需求,尽管我们仍会为所有内容提供 SSL。
              • 为了记录,我的意思是恶意服务器可能只是故意提供不安全的 Javascript,以纯文本形式传输消息。
              猜你喜欢
              • 2010-12-07
              • 1970-01-01
              • 1970-01-01
              • 2018-02-04
              • 2017-07-26
              • 2018-12-14
              • 2012-03-16
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多