I am posting the solution here that I was able to find in case someone comes across the same issue in the future.
It is actually pretty easy to encrypt/decrypt using Rijndael 256 block size with PKCS7 padding by combining two modules rijndael-js
and pkcs7-padding
that available from NPM registry.
rijndael-js
module allows you to encrypt/decrypt using various block sizes: 128, 256, and 192 block sizes - however, it only supports zero paddings. No PKCS7 padding support is provided. So you will either need to rely on another module for PKCS7 padding or do it yourself (at it is not that difficult either).
rijndael-js
will only zero pad the plaintext (data to be encrypted) if its length is not the multiple of the block size. To prevent it from zero-padding your data must first pad the plaintext before encrypting it. In the example below, I use the pkcs7-padding
module from npm for that.
npm install rijndael-js pkcs7-padding --save
This is how you encrypt data
const Rijndael = require('rijndael-js');
const padder = require('pkcs7-padding');
const crypto = require('crypto');
const plainText = Buffer.from('Here is my plain text', 'utf8');
//Pad plaintext before encryption
const padded = padder.pad(plainText, 32); //Use 32 = 256 bits block sizes
const key = crypto.randomBytes(32); //32 bytes key length
const iv = crypto.randomBytes(32); //32 bytes IV
const cipher = new Rijndael(key, 'cbc'); //CBC mode
const encrypted = cipher.encrypt(padded, 256, iv);
This is how to decrypt data
const encrypted = ... //holds our encrypted data
const key = ... // holds our 32 bytes key
const iv = ... //holds our 32 bytes iv
const decipher = new Rijndael(key, 'cbc');
const decryptedPadded = decipher.decrypt(encrypted, 256, iv);
//Remember to un-pad result
const decrypted = padder.unpad(decryptedPadded, 32);
const clearText = decrypted.toString('utf8');
console.log(clearText); //-> Here is my plain text