Search code examples
node.jsencryptionopensslcryptographybouncycastle

What is the equivalent cipher to bouncycastle's PaddedBufferedBlockCipher with AESEngine and PKCS7 padding?


I want to decrypt AES-256 encrypted string using nodejs. I am using crypto module for that.

The string is encrypted using Bouncy castle java library. In Java the cipher is intialsed using:

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine(), new PKCS7Padding());

crypto module of nodejs uses openssl's list of ciphers for intialising it, like:

var decipher = crypto.createDecipher('aes-256-cbc',key);

Which algorithm should I use?

Here is the list of algorithms to choose from:

-bash-4.1$ openssl list-cipher-algorithms|grep AES-256 AES-256-CBC AES-256-CFB AES-256-CFB1 AES-256-CFB8 AES-256-CTR AES-256-ECB AES-256-OFB AES-256-XTS AES256 => AES-256-CBC aes256 => AES-256-CBC


Solution

  • If you encrypt something with a block cipher, you need

    • the block cipher which can take a single block of input and mangle it into a single block of output (for AES the block size is 16 bytes),
    • the mode of operation which enables you to encrypt more than one block in a structured fashion
    • the padding which enables you to encrypt something that is not exactly as long as a multiple of the block size.

    The PaddedBufferedBlockCipher that you've shown only has two of them. The mode of operation is implied to be ECB mode, because it simply consists of applying the block cipher to each block separately.

    You'll get the same behavior in node.js with:

    var decipher = crypto.createDecipheriv('aes-xxx-ecb', key, '');
    

    Exchange the xxx for the size of your key in bits. Valid sizes are 128 bit, 192 bit and 256 bit. Everything else will not work. Also, make sure that you get the encoding of your key right.

    In case you're wondering why createDecipheriv is used here instead of createDecipher, I suggest that you carefully compare the documentation to both of those functions. createDecipher expects a password and not a key.


    Other 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.