我有一個字符串,我想使用JavaScript Web加密API與AES-GCM進行加密。我可以對它進行加密,但是當我解密時,承諾被拒絕,並且我沒有收到各種描述性的錯誤消息。AES-GCM解密拒絕承諾
function aes_encrypt(key, IV, data){
return new Promise(function(resolve, reject){
window.crypto.subtle.encrypt(
{
name: "AES-GCM",
//Don't re-use initialization vectors!
//Always generate a new iv every time your encrypt!
//Recommended to use 12 bytes length
iv: sta(IV),
//Tag length (optional)
tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
},
key, //from generateKey or importKey above
sta(data) //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
//returns an ArrayBuffer containing the encrypted data
resolve(ats(encrypted));
})
.catch(function(err){
console.error(err);
});
});
}
function aes_decrypt(key, IV, data){
return new Promise(function(resolve, reject){
window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: sta(IV), //The initialization vector you used to encrypt
tagLength: 128 //The tagLength you used to encrypt (if any)
},
key, //from generateKey or importKey above
sta(data) //ArrayBuffer of the data
)
.then(function(decrypted){
//returns an ArrayBuffer containing the decrypted data
alert(decrypted);
resolve(ats(new Uint8Array(decrypted)));
//resolve(ats(decrypted));
})
.catch(function(err){
console.error(err);
});
});
}
function ecdh_generate_keypair(){
return new Promise(function(resolve, reject){
window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384" //can be "P-256", "P-384", or "P-521"
},
true, //whether the key is extractable (i.e. can be used in exportKey)
["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
//returns a keypair object
resolve(key);
})
.catch(function(err){
console.error(err);
});
});
}
function ecdh_export(key){
return new Promise(function(resolve, reject){
window.crypto.subtle.exportKey(
"jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
key //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
//returns the exported key data
resolve(keydata);
})
.catch(function(err){
console.error(err);
});
});
}
function ecdh_import(key){
return new Promise(function(resolve, reject){
window.crypto.subtle.importKey(
"jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
key,
{ //these are the algorithm options
name: "ECDH",
namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
},
true, //whether the key is extractable (i.e. can be used in exportKey)
["deriveKey", "deriveBits"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
)
.then(function(privateKey){
//returns a privateKey (or publicKey if you are importing a public key)
resolve(privateKey);
})
.catch(function(err){
console.error(err);
});
});
}
function ecdh_derive_key(pub, priv){
return new Promise(function(resolve, reject){
window.crypto.subtle.deriveKey(
{
name: "ECDH",
namedCurve: "P-384", //can be "P-256", "P-384", or "P-521"
public: pub, //an ECDH public key from generateKey or importKey
},
priv, //your ECDH private key from generateKey or importKey
{ //the key type you want to create based on the derived bits
name: "AES-GCM", //can be any AES algorithm ("AES-CTR", "AES-GCM", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
//the generateKey parameters for that type of algorithm
length: 256, //can be 128, 192, or 256
},
true, //whether the derived key is extractable (i.e. can be used in exportKey)
["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(keydata){
//returns the exported key data
resolve(keydata);
})
.catch(function(err){
console.error(err);
});
});
}
function random_characters(amount){
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < amount; i++){
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
// string-to-arraybuffer
function sta(data){
var enc = new TextEncoder("utf-8");
return enc.encode(data);
}
// arraybuffer-to-string
function ats(data){
var enc = new TextDecoder();
return enc.decode(data);
}
// JSON into and out of the database for cryptokeys
function json_compress(obj){
var s = JSON.stringify(obj);
s = s.replace(/,/g, "♀");
s = s.replace(/{/g, "☺");
s = s.replace(/}/g, "☻");
return s;
}
function json_decompress(str){
str = str.replace(/♀/g, ",");
str = str.replace(/☺/g, "{");
str = str.replace(/☻/g, "}");
return JSON.parse(str);
}
ecdh_generate_keypair().then(function(key){
ecdh_generate_keypair().then(function(key2){
ecdh_derive_key(key2.publicKey, key.privateKey).then(function(aeskey){
var m = "Hello World!";
aes_encrypt(aeskey, "abcdefghijkl", m).then(function(c){
alert(c);
aes_decrypt(aeskey, "abcdefghijkl", c).then(function(r){
alert(r);
});
});
});
});
});
我知道,硬編碼爲AES的IV是一種安全風險,但我只是試圖讓這個工作進行測試。您可以提供的任何幫助非常感謝,因爲這一直在困擾我整天。提前致謝!
編輯:添加了鍍鉻調試錯誤消息
cryptofunctions.js:48 DOMException
(anonymous) @ cryptofunctions.js:48
Promise rejected (async)
(anonymous) @ cryptofunctions.js:47
aes_decrypt @ cryptofunctions.js:31
(anonymous) @ cryptofunctions.js:184
Promise resolved (async)
(anonymous) @ cryptofunctions.js:182
Promise resolved (async)
(anonymous) @ cryptofunctions.js:180
Promise resolved (async)
(anonymous) @ cryptofunctions.js:179
Promise resolved (async)
(anonymous) @ cryptofunctions.js:178
編輯2:決定後整個文件,因爲它似乎所有有關的問題。
即使它可能不是「非常具有描述性「,你能引用這個錯誤信息嗎?什麼是'sta'?你能提供[MCVE]嗎? (強調**完整**) – Kaiido
@Kaiido err是一個變量傳遞給函數時它被調用,並打印錯誤信息我認爲。 sta和ats分別將字符串轉換爲arrayBuffer和arraybuffer。編輯提供進一步的細節。 –
調用'.importKey()'在哪裏? – guest271314