Making CryptoJS and pycrypto compatible

1.6k views Asked by At

I'm trying to figure out how to use the CryptoJS library for AES but the documentation is somewhat scarce.

I've followed their example but I can't seem to decode something that I encoded in PyCrypto

I've formatted as follows:

key = '0f3f0fe38eb5f216cb4ef0649f81d761'
ciphertext = 'Y+gwBI6R37Ko1lQmwZ57gg==FqUSqQ=='

The ciphertext has two components

iv: Y+gwBI6R37Ko1lQmwZ57gg==
encoded message: FqUSqQ==

I tried running the code below but it didn't work. It logs "" in the console. It should be resolving to 'Test'

var decrypted =CryptoJS.AES.decrypt(ciphertext, key);
console.log( decrypted.toString(CryptoJS.enc.Utf8) );

Any pointers would great. Thanks

2

There are 2 answers

0
marcoseu On BEST ANSWER

I ran into this problem as well and unfortunately it was very tricky to get pycrypto to talk to crypto-js. Here are the combination that worked for me:

  1. Use MODE_CFB with segment_size=128 when encrypting in Python
  2. You must pad your string with Pkcs7 as per RFC 2315 [Page 21]
  3. Once you have received the base64 version of ciphertext in JS, you need to wrap it in CryptoJS.lib.CipherParams.create({ ... })

Take a look at the code that works for me (Python 2.7.x):
https://gist.github.com/marcoslin/8026990

0
jhntr On

I don't have direct experience with CryptoJS, but many years of experience with a variety of other crypto libraries. It's almost certainly the case the CryptoJS.AES.decrypt expects a different ciphertext format than the one you're using. Your ciphertext is the contanenation of two separate Base64-encoded entities:

Base64(IV) + Base64(Enc(Message))

If CryptoJS.AES.decrypt expects the IV to be specified as part of the ciphertext (which it may not), and expects Base64-encoded ciphertext input at all (which it may not), then I would try passing:

Base64( (binary IV) + (binary Enc(Message)) )

Looking at the CryptoJS doc, I share your frustration with it. But there's an encryption example with "manually specified IV" that may provide a clue.

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
    var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
    var iv  = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');

    var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
</script>

Sorry I can't be more helpful-