使用JavaScript进行非对称加密密码可行吗?

6
我希望使用JavaScript在用户登录时(使用Ajax),对其密码和用户名进行加密。我知道有几个基于JavaScript的非对称加密库。这是一种可行的策略,以安全地传输密码吗?
我知道SSL存在,但这不是问题的关键。

3
为什么不直接使用HTTPS? - Alin Purcaru
1
@Alin Purcaru:问题已更新 - Chris Laplante
@Marcel Korpel:我只是好奇。根据我在这里得到的反馈,我最终会获得一个SSL证书。 - Chris Laplante
1
您可以免费获取自签名的SSL证书。另请参见http://security.stackexchange.com/questions/1167/where-to-get-an-ssl-certificate-for-personal-website - Marcel Korpel
1
一个糟糕的例子:http://www.woningnet.nl/(查看源代码;呸,它甚至不接受超过8个字节的密码)。 - Marcel Korpel
显示剩余6条评论
6个回答

5
第一步: 不要轻信互联网上的人,我将提出一个弱算法以确保我能够破解它。
第二步: 在计算机安全方面获得博士学位之前,请不要设计自己的算法或在生产系统中实现其他人的算法。
加密不足以保护免受重放攻击的影响,如果攻击者获取了加密密码,则对于身份验证而言,它与未加密密码一样有用。
我建议:
1. 用户输入他们的密码 2. 客户端从服务器请求令牌 3. 服务器返回唯一的随机令牌,并将其存储在用户会话中(由服务器上存储的cookie键入) 4. 客户端使用您的公钥加密密码+令牌,并将其传递给服务器。 5. 服务器使用您的私钥解密此内容,并检查令牌是否与此会话匹配,是否已使用过且不能早于30秒。 6. 服务器检查密码哈希值是否与存储在数据存储器中的用户密码的哈希值匹配。
所有传输的数据仍然可见,因此用户不会获得任何隐私(就像在https中一样)。您的加密算法、加密实现和公钥将是公开的。这是当前大量密码学的情况,大量算法旨在在攻击者知道这一点的情况下保持安全。
这不会防止任何键盘记录器或间谍软件攻击,因为它们将针对密码加密之前的过程。
我不了解在Javascript中实现的非对称加密的实现,但这种方法本质上并不不安全。

1
那么,基于你的第一个观点,我应该相信你提出的系统吗? - Chris Laplante
@SimpleCoder 不是的 :) 我有一种对安全性的兴趣,我相信这会使它更加安全,但我只是邪恶的鲍勃在愚弄你。说真的,我相信我所说的是正确的,但你只能相信我的话,我可能也犯了错误。 - David Waters
@David Waters:这正是我所想的 :). 那么,你实际上是Eve吗? - Chris Laplante
@Marcel Korpel:在向服务器请求令牌之前,您要求用户输入密码,所以30秒只是网络延迟和加密时间。不需要等待用户的时间。我已经澄清了我的回答。 - David Waters
4
即使您拥有博士学位,您仍需要检查您的教授及其教授的学位等级,以确保他们所教授的内容是真正安全的。然后您需要检查这些教授是否有任何隐藏的动机来故意教授不安全的方案。 - Lie Ryan
显示剩余2条评论

4
你可以使用像安全远程密码协议这样的算法提供一个零知识证明,证明你知道密码。窃听者将无法使用此来复制您的登录。但要注意主动攻击者会将您的Javascript代码替换为直接将密码传输给他的内容。
有几个Javascript实现的SRP:

2

不行。攻击者获取密码或加密后的密码都不会有任何区别,因为它们都将以“未加密”的形式发送到服务器,所以可以使用加密后的密码进行登录。

JavaScript 不能用于安全性。必须要使用 HTTPS。


1
为什么一定是这样呢?如果我安装了一个SHA1库(比如这个:http://pajhome.org.uk/crypt/md5/sha1.html),并且只在网络上发送密码的哈希值,那会怎样呢?如果这种方式不安全,那么把SHA1哈希值存储在数据库中不也是不安全的吗? - Zach Rattner
3
@Greg Agnew:无论你如何分类,加密算法必须在用户的客户端机器上使用。这意味着它是公开可读的。即使您通过混淆过程发送了您的方法,也无法阻止这种情况发生。 - Joel Etherton
2
@Zach Rattner - 如果该方法接受已经哈希过的密码,并将其与数据库中的内容进行比较,则它容易受到重放攻击。在数据库中存储哈希并不是不安全的,因为输入是先被哈希然后再进行比较。在OP的情况下,哈希值被直接接受并进行比较。 - Joel Etherton
3
如果每次向服务器发送相同的令牌,则无论攻击者是否拥有您的密码或密码哈希,他们都可以通过身份验证您的服务器。因此,发送密码哈希值可能会防止某些类型的黑客获取您的密码(请参见加盐和彩虹表),但如果您所需的身份验证仅为密码哈希,则不会防止他们进行认证。 - David Waters
1
很抱歉,这不是正确的。使用Javascript实现零知识证明算法以防止被动攻击者是完全可行的。 - Rasmus Faber
显示剩余9条评论

1

我不认为你会从中获得什么好处,肯定少于这样一个数学密集型的JavaScript会带来的性能损失。如果你使用它来加密一段数据并通过HTTP将其发送到服务器,那么虽然你已经保护了黑客无法发现密码是什么,但他们仍然可以通过使用相同的加密数据运行重放攻击来获取访问权限。

唯一可行的保护表单提交的方法是使用HTTPS。我知道设置HTTPS很麻烦,因为证书只适用于一个域,但如果信息真的很关键,那么与尝试在JavaScript中进行加密相比,这是更值得你投入时间的一个选择。


JavaScript 中的数学计算已经非常快了,JavaScript 被认为是慢的,因为它通常与难以抽象和复杂的 DOM 操作过程相关联。请参见此演示(对称加密)。 - Camilo Martin

1

这个模型仍然存在问题,因为你仍然只是在连接中传递文本。如果在加密/解密/比较过程中没有一定的日期措施,你仍然会面临重放攻击的潜在风险。

即使超越了仍然普遍存在的中间人攻击,你仍然会发现你的加密算法和公钥是公开的事实。如果有人得到了一个加密密码,他们将有一个永久的来源来轻松地暴力破解该密码。


最好对它进行彻底的加密。 - Andrew

0

如果您从非验证的通信开始,您始终面临中间人攻击的风险。

无论如何,传输加盐和哈希后的密码总是比传输明文密码要好。因为也许您的登录系统很弱,但至少您没有共享用户的密码(这可能会与另一个系统共享,可能被用于银行账户)。

此外,不要存储该值,而是再次进行加盐和哈希处理。

如果您还使用了非对称加密,您可以增加防止窃听的保护。但同样不能防止中间人攻击。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接