问题
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:
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.
来源:https://stackoverflow.com/questions/37891516/aes-encryption-in-node-js-to-match-expected-decryption-in-python