是否存在AES的客户端Javascript / JQuery实现?

时间:2017-05-02 22:34:53

标签: javascript jquery encryption cryptography aes

首先,我已阅读此article

其次,我在StackOverflow上阅读了这篇文章,虽然它是相对较新的,但大多数有希望的链接已经死了。

第三,有人向我推荐Crypto-JS,但这似乎是基于节点的,因此也就是服务器端。

这让我看了Stanford Javascript Crypto Library看起来很不错,除了我不是一个密码学家,因此我没有资格评估它。

我基本上在寻找一个易于实现的客户端加密库。它将通过SSL提供,其主要目的是在数据到达服务器之前加密,而不是在到达时加密。这只是一个宠物项目/概念证明,但我想做尽可能接近正确的事情。

总而言之,是否存在可信/易于实现的客户端AES加密,或者作为jQuery插件(可疑,我能找到的唯一提供RC4 encryption)或者其他普通的JavaScript的?或者这是一个徒劳的想法?

2 个答案:

答案 0 :(得分:1)

我推荐新的WebCrypto API,这是W3C的下一代标准。

它现在supported by all major browsers开箱即用。 与任何其他基于JS的解决方案相比,它非常易于使用并且非常好performance

以下是我能想到的主要优点:

  • 没有外部库(随浏览器一起提供)
  • 异步(不阻止用户界面)
  • 多线程
  • 硬件加速
  • 近乎原生的性能(比传统的加密库快10倍)
  • Cryptographically secure number generator(它提供对系统安全随机数生成器的直接访问)

有关较旧的浏览器支持,请参阅@rmhrisk's answer

以下是如何使用WebCrypto API进行加密的示例: https://github.com/diafygi/webcrypto-examples#aes-gcm---encrypt

答案 1 :(得分:1)

艾蒂安·马丁大多是对的。

如果你有选择的话,你应该在浏览器中进行任何加密的唯一方法是WebCrypto,它非常好supported by user agents now.

但是,如果您需要使用像IE这样的旧浏览器,您可以使用 - https://github.com/PeculiarVentures/webcrypto-liner,并且基于Webcrypto的代码可以正常工作。

另外一定要使用AES-GCM,这是一种经过验证的AES模式,是正确的选择。

你想要的样子:

function stringToArrayBuffer(str) {
    var buf = new ArrayBuffer(str.length);
    var bufView = new Uint8Array(buf);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

function arrayBufferToString(str) {
    var byteArray = new Uint8Array(str);
    var byteString = '';
    for (var i = 0; i < byteArray.byteLength; i++) {
        byteString += String.fromCodePoint(byteArray[i]);
    }
    return byteString;
}

var text = "I am clear text";
console.log("what we will encrypt:");
console.log(text);

var data = stringToArrayBuffer(text);
console.log("what we encode to:");
console.log(data);

window.crypto.subtle.generateKey({
            name: "AES-GCM",
            length: 256, //can be  128, 192, or 256
        },
        false, //whether the key is extractable (i.e. can be used in exportKey)
        ["encrypt", "decrypt"] //can be "encrypt", "decrypt", "wrapKey", or "unwrapKey"
    )
    .then(function(key) {
        //returns a key object
        console.log("our key:");
        console.log(key);

        window.crypto.subtle.encrypt({
                    name: "AES-GCM",
                    //Don't re-use initialization vectors!
                    //Always generate a new iv every time your encrypt!
                    iv: window.crypto.getRandomValues(new Uint8Array(16)),
                },
                key, //from generateKey or importKey above
                data //ArrayBuffer of data you want to encrypt
            )
            .then(function(encrypted) {
                //returns an ArrayBuffer containing the encrypted data
                console.log("our ciphertext:");
                console.log(new Uint8Array(encrypted));
            })
            .catch(function(err) {
                console.error(err);
            });
    })
    .catch(function(err) {
        console.error(err);
    });