Зашифруйте личный ключ паролем, используя только API-интерфейс WebCrypto

Можно ли зашифровать 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 ответ

Решение

Это, прежде всего, пожалуйста, используйте аутентифицированный режим шифрования, такой как AES-GCM.

Во-вторых, вы должны рассмотреть возможность использования существующего формата, такого как PKCS#8 для этой задачи. Вы можете увидеть PKI.js для библиотеки, которая может помочь вам сделать это.

Другой подход заключается в том, чтобы зашифровать ключ в сообщении CMS, вот пример, который делает именно это: https://pkijs.org/examples/CMSEnvelopedPreDefineDataExample.html

Вы можете посмотреть на него, чтобы увидеть, как сделать связанный webcrypto, даже если вы хотите сделать пользовательский формат.

В-третьих, гораздо лучше не шифровать паролем, все, что зашифровано паролем, будет перемалываться, всегда лучше создать твердый симметричный ключ и использовать его вместо производного пароля.

Если вы используете пароль, обязательно используйте PBDKF2 для его расширения, https://github.com/diafygi/webcrypto-examples. Если вы сделаете это, ваш пример будет работать.

Если вы используете один из существующих форматов для ключей, они естественным образом отправят вас по этому пути.

Другие вопросы по тегам