簡體   English   中英

為什么解密修改后的 AES-CBC 密文解密失敗?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM