Decrypting a string from pycrypto with AES-256-CBC in node.js with unknown IV

Viewed 33

I'm trying to use Node's built-in crypto library to decipher a string encoded by a separate python system. I have only the key used to encrypt, the base64 encoded output, and the python source code.

This is the python code being used:

class AESCipher(object):

    def __init__(self, key):
        self.bs = AES.block_size
        self.key = key

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode()))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

And here's my current best effort at decoding in Node.

function decryptData(encrypted: string, key: string): string {
  const crypto = require('crypto');
  let buff = Buffer.from(encrypted, 'base64'); // decode from base64 to buffer
  let iv = Buffer.from(buff.subarray(0, 16)); // aes block size is 16, first 16 bytes of buffer should be IV
  let content = Buffer.from(buff.subarray(16)); // remainder of buffer should be encrypted content
  let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); 
  let decrypted = decipher.update(content);
  decrypted += decipher.final('utf8');
  return decrypted;
}

However, this gives me

error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

Other info:

  • The key is a known 32 byte UTF-8 string
  • I'm aware there will almost certainly be padding characters I need to strip off, but since that's the first operation in the python encrypt, it should be the last operation in my decrypt, and this is failing at decipher.final
  • I've confirmed that the function parameters being passed in are correct
  • I've tried adding decipher.setAutoPadding(false); since the python code pads the string right away, but it didn't change the error I get
0 Answers
Related