24

Using this Gist I was able to successfully decrypt AES256 in Node.js 0.8.7. Then when I upgraded to Node.js 0.10.24, I now see this error:

TypeError: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
at Decipheriv.Cipher.final (crypto.js:292:27)

Here is the decrypt code from the Gist (shown here for convenience):

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
encryptdata = new Buffer(encryptdata, 'base64').toString('binary');

var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv),
decoded = decipher.update(encryptdata);

decoded += decipher.final();
return decoded;
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv),
encryptdata = encipher.update(cleardata);

encryptdata += encipher.final();
encode_encryptdata = new Buffer(encryptdata, 'binary').toString('base64');
return encode_encryptdata;
}

var cryptkey = crypto.createHash('sha256').update('Nixnogen').digest(),
iv = 'a2xhcgAAAAAAAAAA',
buf = "Here is some data for the encrypt", // 32 chars
enc = AESCrypt.encrypt(cryptkey, iv, buf);
var dec = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc);
console.warn("decrypt all: " + dec);
Sander de Jong
  • 351
  • 6
  • 18
Justin Elkow
  • 2,833
  • 6
  • 28
  • 60
  • I'm also facing a similar issue. Take a look at this http://stackoverflow.com/questions/32038267/getting-error-wrong-final-block-length-while-decyrpting-aes256 – dark_shadow Aug 16 '15 at 18:04
  • Here are some similar questions and answers: [Nodejs decrypt using crypto error wrong final block length](https://stackoverflow.com/q/23111388/608639), [Getting error wrong final block length while decrypting AES256](https://stackoverflow.com/q/32038267/608639), [Decrypt file in Node.js encrypted using OpenSSL](https://stackoverflow.com/q/44482151/608639), [How to decipher string in node.js which is encrypted in crypto.js](https://stackoverflow.com/q/28359128/608639), [What's wrong with node.js crypto decipher?](https://stackoverflow.com/q/12219499/608639) – jww Jun 11 '17 at 10:17
  • It helps me `decipher.setAutoPadding(false);` By default node uses PKCS padding but other langauges C++, Python not using this padding. – Muhammad Shahzad Oct 27 '21 at 06:16

3 Answers3

30

Ok, so there was a change to Crypto in the switch from 0.8 to 0.10 Crypto methods return Buffer objects by default, rather than binary-encoded strings

This means the above code needs to specify encodings.

These four lines:

decoded = decipher.update(encryptdata);
decoded += decipher.final();
encryptdata = encipher.update(cleardata);
encryptdata += encipher.final();

Are changed to:

decoded = decipher.update(encryptdata, 'binary', 'utf8');
decoded += decipher.final('utf8');
encryptdata = encipher.update(cleardata, 'utf8', 'binary');
encryptdata += encipher.final('binary');

This worked for me, but I am open to other suggestions.

Justin Elkow
  • 2,833
  • 6
  • 28
  • 60
  • 1
    Dude you saved me so much time. Works like a charm! – Ryan Wheale May 08 '14 at 21:01
  • 1
    I'm getting the same error, but I'm using a pipeline (passing the decipher variable to `pipe` on the file) to avoid issues with needing the entire file in memory. Any idea what to do in that case? – Michael Jun 30 '16 at 22:12
  • We had this issue with a Heroku app that didn't have an "engines" attribute in the package.json. The version was updated on a deploy without us catching the issue. Thanks! – BradByte Dec 22 '16 at 14:10
  • @Michael I am Facing the same using pipeline ... Any solution?? – Neeraj Walia Sep 28 '18 at 07:23
  • can you help me here [https://stackoverflow.com/questions/52550132/node-js-encrypt-and-decrypt-file?noredirect=1#comment92040944_52550132] – Neeraj Walia Sep 28 '18 at 08:41
  • I was getting the same error as mentioned in the question. I looked at the code and I found that I was trying to decrypt without encrypting the data. – Raj Kumar Jul 06 '19 at 13:35
  • Can you please help me https://stackoverflow.com/questions/68287507/decrypting-selling-partner-api-reports – nats Jul 07 '21 at 14:58
14

As your answer states, those functions work with Buffers now unless you specify an encoding. That said, you'd be better off avoiding binary encoded strings entirely and treat everything as Buffers until you strictly need a string for something. This way you can also use your encryption helpers to process non-text content.

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
    var decipher = crypto.createDecipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        decipher.update(encryptdata),
        decipher.final()
    ]);
}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
    var encipher = crypto.createCipheriv('aes-256-cbc', cryptkey, iv);
    return Buffer.concat([
        encipher.update(cleardata),
        encipher.final()
    ]);
}

var cryptkey = crypto.createHash('sha256').update('Nixnogen').digest(),
iv = new Buffer('a2xhcgAAAAAAAAAA'),
buf = new Buffer("Here is some data for the encrypt"), // 32 chars
enc = AESCrypt.encrypt(cryptkey, iv, buf);
var dec = AESCrypt.decrypt(cryptkey, iv, enc);

console.warn("encrypt length: ", enc.length);
console.warn("encrypt in Base64:", enc.toString('base64'));
console.warn("decrypt all: " + dec.toString('utf8'));
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • I'm also facing a similar issue. http://stackoverflow.com/questions/32038267/getting-error-wrong-final-block-length-while-decyrpting-aes256 Take a look at it and give your valuable inputs – dark_shadow Aug 16 '15 at 18:04
  • 1
    Is it possible to encrypt and decrypt the same field in different files? i keep getting this error `Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length` – kd12345 Mar 04 '21 at 11:26
  • @kd12345 Please post a new question. – loganfsmyth Mar 04 '21 at 17:13
6

My issue was that the string I was passing to my decrypt function was empty. I built in a check for empty strings and I did not receive the message again.

decrypt: function(text){
                if(text.length == 0){
                    return text;
                }
                return this.decipher.update(text, 'hex', 'utf8') + this.decipher.final('utf8');
            }
Lanklaas
  • 2,870
  • 1
  • 15
  • 18