Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

node.js - Getting error "wrong final block length" when decrypting AES256 cipher

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...