CryptoJS AES-128加解密结果异常问题求助
Hey there, let's break down why your AES-128 decryption is returning unexpected results. Looking at your code snippet, there are a few common missteps that are likely causing the problem—let's fix them one by one.
Key Issues in Your Current Implementation
1. You're not persisting/reusing critical values for decryption
When using AES with PBKDF2 key derivation, three values need to stay consistent between encryption and decryption:
- The salt used to generate the AES key (PBKDF2 produces different keys with different salts)
- The IV (initialization vector) for AES-CBC mode (CryptoJS uses CBC by default, and you can't decrypt with a different IV than what was used for encryption)
- The exact PBKDF2 parameters (password, key size, iteration count)
Your code generates random salt and IV, but if you don't save these values and reuse them during decryption, you'll end up trying to decrypt with a mismatched key/IV—guaranteeing garbage results.
2. Incomplete encryption setup (likely missing IV in encryption call)
Your code cuts off at var encrypted = CryptoJS.AES.encryp..., but if you aren't explicitly passing your generated iv_wordArr to the encryption method, CryptoJS will generate its own random IV behind the scenes. This means your manually created IV is unused, and you won't have the correct IV to decrypt later.
Fixed, End-to-End Example
Here's a complete working flow that addresses these issues:
// -------------------------- // Encryption Step // -------------------------- var plain = CryptoJS.lib.WordArray.random(128/8); console.log("Original plaintext (Base64): " + plain.toString(CryptoJS.enc.Base64)); // Generate random salt and IV (must be saved for decryption) var iv_wordArr = CryptoJS.lib.WordArray.random(128/8); var salt = CryptoJS.lib.WordArray.random(128/8); // Derive 128-bit AES key using PBKDF2 var key128Bits = CryptoJS.PBKDF2("12345678", salt, { keySize: 128/32, iterations: 1000 }); // Encrypt with explicit IV (critical for matching decryption) var encrypted = CryptoJS.AES.encrypt(plain, key128Bits, { iv: iv_wordArr }); // Save all required data for decryption (store this somewhere: DB, file, etc.) var savedEncryptionData = { ciphertext: encrypted.ciphertext.toString(CryptoJS.enc.Base64), salt: salt.toString(CryptoJS.enc.Base64), iv: iv_wordArr.toString(CryptoJS.enc.Base64) }; console.log("Saved encryption data:", savedEncryptionData); // -------------------------- // Decryption Step // -------------------------- // Restore salt, IV, and ciphertext from saved data var restoredSalt = CryptoJS.enc.Base64.parse(savedEncryptionData.salt); var restoredIV = CryptoJS.enc.Base64.parse(savedEncryptionData.iv); var restoredCiphertext = CryptoJS.enc.Base64.parse(savedEncryptionData.ciphertext); // Regenerate the EXACT same AES key using the restored salt var decryptionKey = CryptoJS.PBKDF2("12345678", restoredSalt, { keySize: 128/32, iterations: 1000 }); // Create a CipherParams object (required for CryptoJS decryption with raw ciphertext) var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: restoredCiphertext }); // Decrypt using the restored key and IV var decrypted = CryptoJS.AES.decrypt(cipherParams, decryptionKey, { iv: restoredIV }); var decryptedPlaintext = decrypted.toString(CryptoJS.enc.Base64); console.log("Decrypted plaintext (Base64): " + decryptedPlaintext); console.log("Matches original?", decryptedPlaintext === plain.toString(CryptoJS.enc.Base64));
Additional Notes
- If you want to simplify things, you can use CryptoJS's built-in formatted output: when you call
encrypted.toString(), it returns a Base64 string that includes the salt, IV, and ciphertext wrapped in a standard format. You can decrypt this directly withCryptoJS.AES.decrypt(encryptedString, "12345678")(since CryptoJS will auto-extract the salt/IV). This works if you're using the password directly instead of manually handling the PBKDF2 key. - Double-check that all PBKDF2 parameters (password,
keySize,iterations) are identical between encryption and decryption—even a single changed value will generate a different key. - Never hardcode salt or IV in production; always generate them randomly per encryption, but make sure to save them alongside the ciphertext.
内容的提问来源于stack exchange,提问作者MauriF

