Reputation: 81
How can I decrypt an encrypted string like dIwykUwOomuWcdw/QX/Aig==
in AES 256 CBC mode with the key ds8am3wys3pd75nf0ggtvajw2k3uny92
and iv jm8lgqa3j1d0ajus
as the picture below just with javascript (not Nodejs). I used to try with CryptoJs library but the result not like I expected.
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/pbkdf2.js"></script>
<script>
var str = 'dIwykUwOomuWcdw/QX/Aig==';
var key = 'ds8am3wys3pd75nf0ggtvajw2k3uny92';
var iv = 'jm8lgqa3j1d0ajus';
var encrypted = CryptoJS.AES.encrypt("2730007809303", key, { iv: iv });
var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv});
var base64_str = decrypted.toString(CryptoJS.enc.Base64);
console.log(atob(base64_str))
</script>
By the way, how can I convert input string dIwykUwOomuWcdw/QX/Aig==
as encrypted
object above ?
Upvotes: 4
Views: 14071
Reputation: 49141
Your code snippet is almost right. However, the key must not be passed as a string, otherwise CryptoJS will interpret it as a passphrase and generate the actual key and IV from it [1], with an insecure algorithm by the way. Instead, key and IV must be passed as WordArray
, which is easily achieved using the encoders [2]. Since key and IV are Utf8-strings in this example, they must be parsed with the Utf8-encoder. Then you will get the desired ciphertext of the web page. Be aware that encrypt
returns a CipherParams
-object that encapsulates the ciphertext among other data [3]. Furthermore, you don't need the Base64-detour and should decode the decrypted data directly as UTF8-string:
var key = CryptoJS.enc.Utf8.parse('ds8am3wys3pd75nf0ggtvajw2k3uny92'); // Use Utf8-Encoder.
var iv = CryptoJS.enc.Utf8.parse('jm8lgqa3j1d0ajus'); // Use Utf8-Encoder
var encryptedCP = CryptoJS.AES.encrypt("2730007809303", key, { iv: iv });
var decryptedWA = CryptoJS.AES.decrypt(encryptedCP, key, { iv: iv});
var encryptedBase64 = encryptedCP.toString(); // Short for: encryptedCP.ciphertext.toString(CryptoJS.enc.Base64);
var decryptedUtf8 = decryptedWA.toString(CryptoJS.enc.Utf8); // Avoid the Base64 detour.
// Alternatively: CryptoJS.enc.Utf8.stringify(decryptedWA);
console.log("Ciphertext (Base64) : " + encryptedBase64)
console.log("Decrypted data (Utf8): " + decryptedUtf8);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
Note that the CBC-mode and PKCS7-padding are implicitly used, which are the default parameters of CryptoJS [4], so it is not necessary to specify them explicitly.
Update:
If the ciphertext is a string or a WordArray
, a CipherParams
-object must be created from it, because the decrypt
-method expects an object of this type [5]. The entirety of all data encapsulated by the CipherParams
-object can be most easily taken from its definition [6]. In the current case at least the ciphertext must be specified as WordArray
. Optionally a formatter can be specified which determines the formatting strategy of toString()
(if used):
var key = CryptoJS.enc.Utf8.parse('ds8am3wys3pd75nf0ggtvajw2k3uny92'); // Use Utf8-Encoder.
var iv = CryptoJS.enc.Utf8.parse('jm8lgqa3j1d0ajus'); // Use Utf8-Encoder
var ciphertext = CryptoJS.enc.Base64.parse('dIwykUwOomuWcdw/QX/Aig=='); // Use Base64-Encoder.
var encryptedCP = CryptoJS.lib.CipherParams.create({
ciphertext: ciphertext,
formatter: CryptoJS.format.OpenSSL // Optional, but required for encryptedCP.toString()
});
var decryptedWA = CryptoJS.AES.decrypt(encryptedCP, key, { iv: iv});
var encryptedBase64 = encryptedCP.toString(); // Short for: encryptedCP.ciphertext.toString(CryptoJS.enc.Base64);
var decryptedUtf8 = decryptedWA.toString(CryptoJS.enc.Utf8); // Avoid the Base64 detour.
// Alternatively: CryptoJS.enc.Utf8.stringify(decryptedWA);
console.log("Ciphertext (Base64) : " + encryptedBase64)
console.log("Decrypted data (Utf8): " + decryptedUtf8);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
Upvotes: 6