0

I have the following Python script for decryption:

from Crypto.Cipher import AES

shared_secret = raw_input('Enter crypted_shared_secret: ').strip()
cipher = AES.new(shared_secret.decode('base64'), AES.MODE_ECB)

blob = raw_input('Enter crypted_blob: ').strip()
plain = cipher.decrypt(blob.decode('base64'))

print(plain)

I'm trying to generate the values that would produce the original blob using that script, using Node. Here is my attempt:

const Crypto = require('crypto');

var shared_secret = Crypto.randomBytes(32);
var cipher = Crypto.createCipher('aes-256-ecb', shared_secret);
crypted_blob = cipher.update(blob, 'utf8', 'base64') + cipher.final('base64');

I can only modify the Node.js script, but I'm not sure where it's going wrong.

1 Answer 1

2

You need to encode the shared secret key to Base64 only after you use it for encryption:

var shared_secret = Crypto.randomBytes(32);
var cipher = Crypto.createCipheriv('aes-256-ecb', shared_secret, "");
crypted_blob = cipher.update(blob, 'utf8', 'base64') + cipher.final('base64');
// send `shared_secret.toString('base64')`

Other problems:

  • crypto.createCipher assumes the shared secret is a password and not a key, which is why it will use a bad key derivation (OpenSSL-compatible).
  • Node.js' crypto module automatically applies PKCS#7 padding (same as PKCS#5 padding), but PyCrypto doesn't apply any padding on its own. So you either need to use the same unpadding in Python or you can disable padding in node.js with Cipher.setAutoPadding(false);, but then you will have to provide plaintexts that are a multiple of the block size (16 byte for AES).

Security considerations:

  • Never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.
Sign up to request clarification or add additional context in comments.

3 Comments

I still can't get this to work. I have cut the RSA code which was working, the AES is the part that doesn't seem to work. If I open up node and start with blob = 'Hello world' and then run the 4 lines of code, I get e.g. FH1hDHh49uGiWZhNCtg5Dw== as crypted_blob. Then I can run shared_secret.toString('base64') and get e.g. bUQXpYLhZnR+9vKTU8txkRo7O6j7nrks1MJnxI/YIGo=. Then I open up Python, enter the latter as shared_secret and the former as blob, but I still get a scrambled string (wrong decryption).
Yes, I missed that you've used the wrong method in node.js. See my edit.
That worked! Will look into replacing ECB with CBC, thanks for the tip!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.