11

我想在已经存在的项目上使用 Web Cryptography API。要加密和解密某些东西,我必须使用 CryptoKey,但是当我将 CryptoKey 保存到 localStorage 时,它​​只保存字符串(CryptoKey)而不是对象。

是否可以以简单类型(字符串)序列化/转换 CryptoKey?

我的解密方法是

function decryptDataWithAES(keyName)
{
    var decrypt_promise; 
    var aesKey = localStorage.getItem(keyName + 'key')
    var item = localStorage.getItem(keyName)
    var invokeVektor = localStorage.getItem(keyName + 'vector')
    console.log("aesKey", aesKey )

    crypto.subtle.decrypt({ name: "AES-CBC", iv: invokeVektor }, aesKey, item).then(function (result) {
        decrypted_data = new Uint8Array(result); decrypted_data = new Uint8Array(result);

        decrypt_promise = convertArrayBufferViewtoString(decrypted_data);
        console.log('decryptDataWithAES ' + decrypt_promise);
        return decrypt_promise; 
    },
        function(e){
            console.log(e.message);
        }
    );
}

错误信息当然是:

无法在“SubtleCrypto”上执行“解密”:参数 2 不是“CryptoKey”类型。2localStorageHandler.js:39 CryptoPromise[对象 CryptoKey]

如果我不使用 localStorage 解密,则加密数据没有问题。

4

2 回答 2

8

考虑在将其保存到 localStorage 之前使用 crypto.subtle.exportKey() 和 crypto.subtle.importKey(),因此您的解密代码将如下所示:

function decryptDataWithAES(keyName)
{
    var decrypt_promise; 

    // read raw value of aesKey
    var aesKey_RAW = localStorage.getItem(keyName + 'key')
    var importPromise = crypto.subtle.importKey('raw', aesKey_RAW, 'AES-CBC', true, ['encrypt','decrypt']);

    importPromise.then(function(aesKey){

    var item = localStorage.getItem(keyName)
    var invokeVektor = localStorage.getItem(keyName + 'vector')

        console.log("aesKey", aesKey )

        crypto.subtle.decrypt({ name: "AES-CBC", iv: invokeVektor }, aesKey, item).then(function (result) {
            decrypted_data = new Uint8Array(result); decrypted_data = new Uint8Array(result);

            decrypt_promise = convertArrayBufferViewtoString(decrypted_data);
            console.log('decryptDataWithAES ' + decrypt_promise);
            return decrypt_promise; 
        },
            function(e){
                console.log(e.message);
            }
        );

    }, function(e){ console.log(e.message) } );
}

要将密钥以原始格式保存在 localStorage 中:

function saveKeyInLocalStorage(keyName, aesKey){
   var exportPromise = crypto.subtle.exportKey('raw',aesKey);
   exportPromise.then(function(aesKey_RAW){ 
        localStorage.setItem(keyName + 'key' , aesKey_RAW);
        console.log("saved.");
   });
}

请注意,exportKey() 和 importKey() 方法都返回一个承诺。

于 2016-05-17T18:05:43.833 回答
2

某些键无法以 RAW 格式导出。但到目前为止,似乎到处都支持 JWK(json web key)格式,因此您可以使用它。

// to store the key:
window.crypto.subtle.exportKey("jwk", key)
.then(e=>localStorage.setItem("webkey",JSON.stringify(e)));

同样,您可以 importKey() 回来,这取决于您的密钥算法。有关语法,请参阅https://github.com/diafygi/webcrypto-examples/

于 2017-09-20T11:25:57.687 回答