I want to use Web Cryptography API on an already existing project. To encrypt and decrypt something I have to use an CryptoKey, but when I save to CryptoKey into localStorage it only saves the String (CryptoKey) instead of the object.
Is it possible to serialize / convert an CryptoKey in an simple type (string)?
My decrypting method is
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);
}
);
}
The error message is of course:
Failed to execute 'decrypt' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. 2localStorageHandler.js:39 CryptoPromise[object CryptoKey]
If I decrypt without using localStorage there is no problem with encrypting the data.
Consider using crypto.subtle.exportKey() and crypto.subtle.importKey() before saving it in localStorage, so your decryption code would be like this:
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) } );
}
To save your key in raw format in 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.");
});
}
Note that both exportKey() and importKey() methods returns a promise.
Some of the keys cannot be exported in RAW format. But so far it seems the JWK (json web key) format is supported everywhere, so you can use it.
// to store the key:
window.crypto.subtle.exportKey("jwk", key)
.then(e=>localStorage.setItem("webkey",JSON.stringify(e)));
Similarly you can importKey() back, this varies depending on your key algo. For syntax, see https://github.com/diafygi/webcrypto-examples/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With