Getting error "wrong final block length" when decrypting AES256 cipher

11,706

This question is two years old at the time of this writing, but it has quite a few views, so I hope this answer will still prove useful to someone who might come across it.

The problem here is that encryptText works fine, but it's not returning a string. It's returning a Buffer. decryptText is expecting a string, not a Buffer, so it tries to read it as though it were a Buffer and you get the error that you received.

This is a simple fix. We just need to serialise the Buffer to a string when we encrypt text, and deserialise the encrypted string we receive when we decrypt text.

In this example, I use base64 encoding because it is fairly compact when representing binary data.

var config = {
  cryptkey: crypto.createHash('sha256').update('Nixnogen').digest(),
  iv: 'a2xhcgAAAAAAAAAA'
}

function encryptText (text) {
  console.log(config.cryptkey)
  var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv)
  return Buffer.concat([
    cipher.update(text),
    cipher.final()
  ]).toString('base64') // Output base64 string
}

function decryptText (text) {
  console.log(config.cryptkey)
  if (text === null || typeof text === 'undefined' || text === '') {
    return text
  }
  var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv)
  return Buffer.concat([
    decipher.update(text, 'base64'), // Expect `text` to be a base64 string
    decipher.final()
  ]).toString()
}

var encrypted = encryptText('text') // 8xXuS7jLG6crqJFHHB5J5A==
var decrypted = decryptText(encrypted) // text
Share:
11,706
dark_shadow
Author by

dark_shadow

Updated on June 04, 2022

Comments

  • dark_shadow
    dark_shadow almost 2 years

    I'm facing exactly the same problem mentioned in this thread while encrypting and decrypting using AES.

    crypto.js:202
    var ret = this._handle.final(); ^ Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
    at Error (native)
    at Decipher.Cipher.final (crypto.js:202:26)

    These are my encrypt and decrypt functions:

    var config = {
    cryptkey: crypto.createHash('sha256').update('Nixnogen').digest(),
    iv: "a2xhcgAAAAAAAAAA"
    };
    
    function encryptText(text){
        console.log(config.cryptkey);
            var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv);
            var crypted = cipher.update(text,'utf8','binary');
            crypted += cipher.final('binary');
        crypted = new Buffer(crypted, 'binary').toString('base64');
            return crypted;
    }
    
    function decryptText(text){
        console.log(config.cryptkey);
            if (text === null || typeof text === 'undefined' || text === '') {return text;};
        text = new Buffer(text, 'base64').toString('binary');
            var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv);
            var dec = decipher.update(text,'binary','utf8');
            dec += decipher.final('utf8');
            return dec;
    }
    

    I've set "node": ">=0.10.0" in my package.json.

    Can anyone tell me how to fix it? I have tried solutions mentioned in the thread but none of them are working for me.

    Updates:

    I've tried solutions mentioned in the thread but none of them are working for me. I think there might be a different solution for this and hence, rather than polluting the existing thread, decided to create a new one. Also, if I continue this on the existing thread it might confuse future candidates for the right solution.

    Update 2:

    For the second solution mentioned in the thread, I have the following code, but it is also giving me the same error:

    function encryptText(text){
        console.log(config.cryptkey);
            var cipher = crypto.createCipheriv('aes-256-cbc', config.cryptkey, config.iv);
        return Buffer.concat([
            cipher.update(text),
            cipher.final()
        ]);
    }
    
    function decryptText(text){
        console.log(config.cryptkey);
            if (text === null || typeof text === 'undefined' || text === '') {return text;};
            var decipher = crypto.createDecipheriv('aes-256-cbc', config.cryptkey, config.iv);
        return Buffer.concat([
            decipher.update(text),
            decipher.final()
        ]);
    }
    

    Also, I'm using these functions as getters and setters for a field in my mongodb database using mongoose. I don't think doing so will cause any issues, but I still thought it would be a good idea to mention this.

    Update 3:

    I'm trying to encrypt a Facebook access token and decrypt an encrypted Facebook access token.

    To reproduce the error, you can try encrypting this token:

    ASDFGHJKLO0cBACJDJoc25hkZAzcOfxhTBVpHRva4hnflYEwAHshZCi2qMihYXpS2fIDGsqAcAlfHLLo273OWImZAfo9TMYZCbuZABJkzPoo4HZA8HRJVCRACe6IunmBSMAEgGVv8KCLKIbL6Gf7HJy9PplEni2iJ06VoZBv0fKXUvkp1k7gWYMva1ZAyBsWiDiKChjq3Yh1ZCdWWEDRFGTHYJ

    Encryption will work fine and you will get an encrypted string.

    Now try decrypting the encrypted string which you got in the previous step. You will get the error.