仅使用WebCrypto API使用密码加密私钥

时间:2017-04-12 15:46:44

标签: javascript encryption passwords aes webcryptoapi

是否可以使用字符串作为加密密钥加密CryptoKey(私钥)并仅使用WebCryptoAPI? 我实现了一个函数,但是我收到了以下错误:

Uncaught (in promise) DOMException: AES key data must be 128 or 256 bits

另外,我的功能。

function encryptPrivateKey() {
    var promise = new Promise(function (resolve, reject) {
        try {
            var key = new TextEncoder().encode(pwd);
            var iv = crypto.getRandomValues(new Uint8Array(12));
            var alg = {name: 'AES-CTR', iv: iv};
            window.crypto.subtle.importKey('raw', key, alg, false, ['encrypt']).then(function (key) {
                window.crypto.subtle.encrypt(alg, key, privateKeyPEM).then(function (key) {
                    privateKey = key;
                })
            });
            resolve(privateKey);
        } catch (err) {
            reject(Error(err));
        }

    });
    return promise.then(function (result) {
        return result;
    }, function (err) {
        console.log(err);
    });
}

1 个答案:

答案 0 :(得分:4)

首先,请使用经过身份验证的加密模式,例如AES-GCM。

其次,您应该考虑使用PKCS#8等现有格式来执行此任务。您可以看到可以帮助您执行此操作的库的PKI.js。

另一种方法是将密钥加密成CMS消息,这里有一个示例:https://pkijs.org/examples/CMSEnvelopedPreDefineDataExample.html

即使您想要自定义格式,您也可以查看它以了解如何进行关联的webcrypto。

第三,不用密码加密要好得多,用密码加密的东西都是可以磨削的,生成一个坚固的对称密钥并使用它而不是派生密码总是更好。

如果您使用密码,请务必使用PBDKF2来扩展密码https://github.com/diafygi/webcrypto-examples#pbkdf2。如果你这样做,上面的样本将最终起作用。

如果您使用其中一种现有格式的密钥,它们会自然地向您发送此路径。