我必须通过未加密的频道(HTTP,而不是HTTPS)通过JavaScript AJAX调用传输一些敏感信息。
我想对数据进行加密,但JavaScript方面的加密意味着我公开了密钥,这使得对称加密只是一种默默无闻的安全措施。
JavaScript是否有任何非对称加密?这样,我可以保密服务器解密密钥。 (我不担心Server> JavaScript消息的安全性,只关注某个JavaScript> Server消息的安全性)
答案 0 :(得分:13)
你根本需要加密的原因可能是防止中间人。在某些情况下,攻击者无法对流量进行嗅探而无法对其进行更改。这种解决方案可以抵御这种威胁,但它根本无法保护能够修改流量的中间人。
如果攻击者可以更改流量,那么他也可以更改执行加密的脚本。最容易的攻击就是从脚本中完全删除加密。如果您没有https,并且可以使用中间人(几乎在所有情况下都是这种情况)那么您对提交到最后的html或javascript没有任何控制权用户。攻击者可能会完全重写您的HTML代码和javascript,禁用加密,在您的表单中创建新的表单字段等.Https是网络渠道中安全通信的先决条件。
答案 1 :(得分:7)
我做到了。我使用此JavaScript客户端不对称RSA加密来阻止通过HTTP以纯文本格式发送登录凭据。
目标是防止基于网络嗅探的登录请求重播攻击。当然,这不像HTTPS那么安全,因为它不会抵御中间人攻击,但它对本地网络来说已经足够了。
客户端加密使用基于Travis Tridwell's excellent work的JSBN。 Travis的网页还可以生成私有和公共RSA密钥(如果您懒得使用openssl
)。密钥以PKCS#1 PEM格式生成。我加密username+password+timeInMs+timezone
,以便加密内容在每次登录时都会更改。
在服务器端,我的Java代码读取使用Apache JMeter's org.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");
然后我检查客户端时间戳/时区是否与服务器端时间戳/时区匹配。如果延迟少于几秒,则登录过程继续。否则,该请求被视为重放攻击,登录失败。
答案 2 :(得分:3)
这个问题好像有你所追求的,Javascript cryptography library to sign form data in browser PGP链接:http://www.hanewin.net/encrypt/有RSA
答案 3 :(得分:3)
服务器>通过HTTPS发送的JavaScript消息?
如果没有,没有什么能阻止中间人改变脚本。如果有权访问未加密数据的代码遭到破坏,任何加密都将毫无用处。
答案 4 :(得分:3)
非对称公钥/私钥是执行此操作的唯一方法。为了防止MIM攻击,服务器可以使用用户密码对公钥进行散列,然后用户(在浏览器中)重新计算散列 - 如果它们匹配,则用户可以确信从服务器发送的公钥没有被篡改 - 这取决于只有服务器和用户知道用户密码的事实。
PS我想把它写成评论,因为这比答案更合适,但我没有足够的观点:)