24

我必须通过未加密的通道(HTTP,而不是 HTTPS)通过 JavaScript AJAX 调用传输一些敏感信息。

我想加密数据,但是 JavaScript 端的加密意味着我公开了密钥,这使得对称加密只是一种隐蔽的安全练习。

JavaScript 有非对称加密吗?这样,我可以将服务器解密密钥保密。(我不担心 Server > JavaScript 消息的安全性,只关心某个 JavaScript > Server 消息的安全性)

4

5 回答 5

15

您完全需要加密的原因可能是为了防止中间人。在某些情况下,攻击者能够嗅探流量而无法对其进行更改。该解决方案可以抵御这种威胁,但它根本无法抵御能够修改流量的中间人。

如果攻击者可以更改流量,那么他也可以更改执行加密的脚本。最简单的攻击是从脚本中完全删除加密。如果您没有 https,并且中间人是可能的(几乎在每种情况下都是这种情况),那么您根本无法控制最后呈现的 html 或 javascript用户。攻击者可能会完全重写您的 html 代码和 javascript、禁用加密、在您的表单中创建新的表单字段等。Https 是网络通道中安全通信的先决条件。

于 2011-05-25T07:54:36.827 回答
11

我已经做到了。我使用此 JavaScript 客户端非对称 RSA 加密来防止登录凭据通过 HTTP 以纯文本形式发送。

目标是防止基于网络嗅探的登录请求重放攻击。当然,这不如 HTTPS 安全,因为它无法抵抗中间人攻击,但对于本地网络来说已经足够了。

客户端加密使用Travis Tridwell基于JSBN的优秀作品。Travis 的网页还可以生成私钥和公钥 RSA 密钥(如果您懒得使用openssl)。密钥以 PKCS#1 PEM 格式生成。我进行username+password+timeInMs+timezone了加密,以便每次登录时加密的内容都会发生变化。

在服务器端,我的 Java 代码使用Apache JMeterorg.apache.jmeter.protocol.oauth.sampler.PrivateKeyReader读取 PKCS#1 PEM 文件:

PrivateKey pk = (new PrivateKeyReader("myPrivateKeyFile.pem")).getPrivateKey();

然后我使用解密加密的内容

byte[] enc = DatatypeConverter.parseBase64Binary(clientData);
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, pk);
byte[] dec = rsa.doFinal(enc);
String out = new String(dec, "UTF8");

然后我检查客户端时间戳/时区是否与服务器端时间戳/时区匹配。如果延迟少于几秒钟,登录过程将继续。否则该请求被视为重放攻击,登录失败。

于 2014-02-03T15:24:18.583 回答
4

非对称公钥/私钥是做到这一点的唯一方法。为了防止 MIM 攻击,服务器可以使用用户密码散列公钥,然后用户(在浏览器中)重新计算散列 - 如果它们匹配,那么用户可以确信从服务器发送的公钥没有被篡改 - 这取决于只有服务器和用户知道用户密码的事实。

PS我想把它写成评论,因为这比答案更合适,但我没有足够的积分:)

有关示例,请参见:openpgp.js

于 2014-05-16T16:37:16.943 回答
3

这个问题似乎有你所追求的,在浏览器中签署表单数据的 Javascript 加密库PGP 链接:http ://www.hanewin.net/encrypt/有 RSA

于 2011-05-24T21:22:54.103 回答
3

服务器 > JavaScript 消息是否通过 HTTPS 发送?

如果没有,没有什么能阻止中间人更改脚本。如果有权访问未加密数据的代码被泄露,任何加密都将毫无用处。

于 2011-05-24T21:23:17.497 回答