我想在现有项目中使用Web Cryptography API。 要加密和解密我必须使用CryptoKey的东西,但是当我将CryptoKey保存到localStorage时,它只保存String(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);
}
);
}
错误信息当然是:
无法执行'解密' on' SubtleCrypto':参数2不属于' CryptoKey'。 2localStorageHandler.js:39 CryptoPromise [object CryptoKey]
如果我在不使用localStorage的情况下进行解密,则加密数据没有问题。
答案 0 :(得分:5)
在将其保存在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()方法都返回一个promise。
答案 1 :(得分:0)
某些密钥无法以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/