[英]AES-CBC decryption node.js vs. forge digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
[英]Why does decrypting modified AES-CBC ciphertext fail decryption?
我正在嘗試熟悉加密/解密。 我正在使用 deno,因為它支持 web 加密 API。
我可以使用 AES-CBC 加密和解密以取回原始明文。
我現在做的是加密,然后手動修改密文,然后解密。 我的期望是這仍然有效,因為我了解 AES-CBC 不提供完整性和真實性檢查。 (AES-GCM 就是 AEAD)
但是當我修改密文並嘗試解密時,它失敗並出現以下錯誤:
error: Uncaught (in promise) OperationError: Decryption failed
let deCryptedPlaintext = await window.crypto.subtle.decrypt(param, key, asByteArray);
^
at async SubtleCrypto.decrypt (deno:ext/crypto/00_crypto.js:598:29)
at async file:///Users/me/delete/run.js:33:26
AES-CBC 是否也有完整性檢查? 或者為什么解密失敗?
在 Deno 中,我在圍繞服務器和客戶端加密 jwt 時遇到了類似的問題,並且出於同樣的原因不能依賴 TextDecoder class:
error: OperationError: Decryption failed
幾個小時后,我到處玩,找到了一個解決方案,有點棘手,但做得對:
(async ()=> { const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); const rawKey = crypto.getRandomValues(new Uint8Array(16)); // we import the key that we have previously generated const cryptoKey = await crypto.subtle.importKey( "raw", rawKey, "AES-CBC", true, ["encrypt", "decrypt"], ); // we generate the IV const iv = crypto.getRandomValues(new Uint8Array(16)); // here is the string we want to encrypt const stringToEncrypt = "foobar" // we encrypt const encryptedString = await crypto.subtle.encrypt( { name: "AES-CBC", iv: iv }, cryptoKey, textEncoder.encode(stringToEncrypt), ); // we transform the encrypted string to an UInt8Array const uint8ArrayEncryptedString = new Uint8Array(encryptedString); // we transform the Array to a String so we have a representation we can carry around const stringifiedEncryption = String.fromCharCode(...uint8ArrayEncryptedString); /* now is time to decrypt again the message, so we transform the string into a char array and for every iteration we transform the char into a byte, so in the end we have a byte array */ const stringByteArray = [...stringifiedEncryption].map((v) => v.charCodeAt(0)) // we transform the byte array into a Uint8Array buffer const stringBuffer = new Uint8Array(stringByteArray.length); // we load the buffer stringByteArray.forEach((v, i) => stringBuffer[i] = v) // we decrypt again const againDecrString = await crypto.subtle.decrypt( { name: "AES-CBC", iv: iv }, cryptoKey, stringBuffer, ); console.log(textDecoder.decode(againDecrString)) })()
對於出於相同目的依賴 class 的一些人,我建議您使用此解決方案。 底層實現 pheraps 在來回轉換字符串時丟失了一些信息(加密后我需要它作為字符串),因此解密失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.