61

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

致热切的反对者:如何通过 HTTP 安全地发送密码?没有给出任何明智的解决方案,我处于另一种情况。

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

4

11 回答 11

80

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

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

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

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

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

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

于 2010-01-05T00:22:04.470 回答
24

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

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

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

于 2010-01-05T03:20:03.707 回答
12

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

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

于 2010-01-05T00:16:54.357 回答
5

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

但我相信这个和使用散列函数都容易受到重放攻击。所以,要小心。

于 2010-01-05T00:47:51.200 回答
4

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

没有 SSL?没有安全感。

于 2010-01-05T00:13:10.150 回答
1

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

于 2010-01-05T00:14:16.297 回答
1

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

于 2010-01-05T00:15:04.093 回答
1

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

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

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

于 2010-01-05T00:32:21.673 回答
1

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

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

于 2010-01-05T02:01:27.063 回答
0

-- 英语 -- 我在想一些东西,但我不知道它是否真的很安全。如果您可以将表单放入 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埃尔算法。

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

于 2013-06-30T20:07:07.477 回答
0

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

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

于 2015-12-09T00:30:26.580 回答