Awesome FOSS Logo
Discover awesome open source software
Launched 🚀🧑‍🚀

Getting pycrypto and NodeJS crypto package to play together

Categories

Recently on a project I’ve been working on, I’ve had to do some cross-programming language encryption. More specifically, I’ve had to encrypt data in Python with pycrypto (which is an excellent library), and decrypt that same data after sending it across the network in nodejs. Here’s what I got stuck on, and other random things that worked for me.

  1. If you’re trying to send the data just over the wire (ex. using requests and just sending the encrypted binary string that comes out of pycrypto’s AES module for example), you’re going to have a bad time. Base64 encode the encrypted data you want to send before you send it across the wire. If you don’t, you’ll get gibberish (escaped/contorted by node), and you won’t be happy with it.

  2. While pycrypto is pretty easy to work with, I did not find it easy (from reading the docs) to use node’s crypto package for aes-128-cbc (which I was doing just for testing purposes). Start with a static case (same key on both sides, same IV on both sides, but pass the encrypted data) to save yourself headaches about what’s being properly converted and what’s not. This way, you only have to worry about converting the actual encrypted data from base64.

  3. Log log log — Know exactly what’s coming out of python and what’s going into node.

  4. IV/Padding will get you. Most places suggest that you just use a sha256 hash to get up to the right length, but I didn’t do that (at the beginning I just used well-formed keys and plaintext). I did find it important to know the number of bytes that the IV was going to offset you (especially if you’re printing, you should start seeing the IV reproduced relatively quickly)

  5. Remember to call createDecipheriv to create your deciphering crypto object. Also, remember to call it’s setAutoPadding (where necessary), update, and final functions.

There don’t seem to be many guides that focus on going from python to nodejs, so hope this helps someone out:

Here’s what my code ended up looking like:

`Recently on a project I’ve been working on, I’ve had to do some cross-programming language encryption. More specifically, I’ve had to encrypt data in Python with pycrypto (which is an excellent library), and decrypt that same data after sending it across the network in nodejs. Here’s what I got stuck on, and other random things that worked for me.

  1. If you’re trying to send the data just over the wire (ex. using requests and just sending the encrypted binary string that comes out of pycrypto’s AES module for example), you’re going to have a bad time. Base64 encode the encrypted data you want to send before you send it across the wire. If you don’t, you’ll get gibberish (escaped/contorted by node), and you won’t be happy with it.

  2. While pycrypto is pretty easy to work with, I did not find it easy (from reading the docs) to use node’s crypto package for aes-128-cbc (which I was doing just for testing purposes). Start with a static case (same key on both sides, same IV on both sides, but pass the encrypted data) to save yourself headaches about what’s being properly converted and what’s not. This way, you only have to worry about converting the actual encrypted data from base64.

  3. Log log log — Know exactly what’s coming out of python and what’s going into node.

  4. IV/Padding will get you. Most places suggest that you just use a sha256 hash to get up to the right length, but I didn’t do that (at the beginning I just used well-formed keys and plaintext). I did find it important to know the number of bytes that the IV was going to offset you (especially if you’re printing, you should start seeing the IV reproduced relatively quickly)

  5. Remember to call createDecipheriv to create your deciphering crypto object. Also, remember to call it’s setAutoPadding (where necessary), update, and final functions.

There don’t seem to be many guides that focus on going from python to nodejs, so hope this helps someone out:

Here’s what my code ended up looking like:

`

Obviously — under normal circumstances, NEVER send the key in plaintext, obviously. Also, Authentication is important, to prevent things like replay attacks — it is not enough just to encrypt, without proper authentication.

From there, I use requests to send that json bundle across the wire to another computer running node where:

``Recently on a project I’ve been working on, I’ve had to do some cross-programming language encryption. More specifically, I’ve had to encrypt data in Python with pycrypto (which is an excellent library), and decrypt that same data after sending it across the network in nodejs. Here’s what I got stuck on, and other random things that worked for me.

  1. If you’re trying to send the data just over the wire (ex. using requests and just sending the encrypted binary string that comes out of pycrypto’s AES module for example), you’re going to have a bad time. Base64 encode the encrypted data you want to send before you send it across the wire. If you don’t, you’ll get gibberish (escaped/contorted by node), and you won’t be happy with it.

  2. While pycrypto is pretty easy to work with, I did not find it easy (from reading the docs) to use node’s crypto package for aes-128-cbc (which I was doing just for testing purposes). Start with a static case (same key on both sides, same IV on both sides, but pass the encrypted data) to save yourself headaches about what’s being properly converted and what’s not. This way, you only have to worry about converting the actual encrypted data from base64.

  3. Log log log — Know exactly what’s coming out of python and what’s going into node.

  4. IV/Padding will get you. Most places suggest that you just use a sha256 hash to get up to the right length, but I didn’t do that (at the beginning I just used well-formed keys and plaintext). I did find it important to know the number of bytes that the IV was going to offset you (especially if you’re printing, you should start seeing the IV reproduced relatively quickly)

  5. Remember to call createDecipheriv to create your deciphering crypto object. Also, remember to call it’s setAutoPadding (where necessary), update, and final functions.

There don’t seem to be many guides that focus on going from python to nodejs, so hope this helps someone out:

Here’s what my code ended up looking like:

`Recently on a project I’ve been working on, I’ve had to do some cross-programming language encryption. More specifically, I’ve had to encrypt data in Python with pycrypto (which is an excellent library), and decrypt that same data after sending it across the network in nodejs. Here’s what I got stuck on, and other random things that worked for me.

  1. If you’re trying to send the data just over the wire (ex. using requests and just sending the encrypted binary string that comes out of pycrypto’s AES module for example), you’re going to have a bad time. Base64 encode the encrypted data you want to send before you send it across the wire. If you don’t, you’ll get gibberish (escaped/contorted by node), and you won’t be happy with it.

  2. While pycrypto is pretty easy to work with, I did not find it easy (from reading the docs) to use node’s crypto package for aes-128-cbc (which I was doing just for testing purposes). Start with a static case (same key on both sides, same IV on both sides, but pass the encrypted data) to save yourself headaches about what’s being properly converted and what’s not. This way, you only have to worry about converting the actual encrypted data from base64.

  3. Log log log — Know exactly what’s coming out of python and what’s going into node.

  4. IV/Padding will get you. Most places suggest that you just use a sha256 hash to get up to the right length, but I didn’t do that (at the beginning I just used well-formed keys and plaintext). I did find it important to know the number of bytes that the IV was going to offset you (especially if you’re printing, you should start seeing the IV reproduced relatively quickly)

  5. Remember to call createDecipheriv to create your deciphering crypto object. Also, remember to call it’s setAutoPadding (where necessary), update, and final functions.

There don’t seem to be many guides that focus on going from python to nodejs, so hope this helps someone out:

Here’s what my code ended up looking like:

`

Obviously — under normal circumstances, NEVER send the key in plaintext, obviously. Also, Authentication is important, to prevent things like replay attacks — it is not enough just to encrypt, without proper authentication.

From there, I use requests to send that json bundle across the wire to another computer running node where:

``

Important to note that to strip the base64 encoding from the incoming data, you create a buffer that has base64 encoding. This buffer, you can pass directly to the decipher object, but note that python produces BYTE STRINGs (so once the base64 encoding is gone, you’ll have a byte string to deal with), so the input encoding to the decipher object must be ‘binary’.

If this doesn’t help you, do some google searching, and wander in the desert, and hopefully it will come to you (or an experiment will work out)!

This problem has had me banging my head for days, but definitely very rewarding to finally get past.