2014-01-22 10 views
9

Mit diesem Gist konnte ich erfolgreich AES256 in Node.js 0.8.7 entschlüsseln. Dann, wenn ich auf Node.js aktualisiert 0.10.24, ich sehe jetzt diesen Fehler:Entschlüsseln von AES256 mit node.js gibt falsche endgültige Blocklänge zurück

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

Hier wird der Entschlüsselungs-Code aus dem Gist (hier der Einfachheit halber gezeigt):

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); 
+0

Ich bin auch mit einem ähnlichen Problem konfrontiert. Werfen Sie einen Blick auf diese http://stackoverflow.com/questions/32038267/getting-error-wrong-final-block-length-while-decyrpting-aes256 –

+0

Hier sind einige ähnliche Fragen und Antworten: [Nodejs entschlüsseln mit Crypto-Fehler falsch letzte Blocklänge] (https://stackoverflow.com/q/23111388/608639), [Fehler beim Abschließen der letzten Blocklänge beim Entschlüsseln von AES256] (https://stackoverflow.com/q/32038267/608639), [Datei entschlüsseln in Node.js, die mit OpenSSL verschlüsselt wurden] (https://stackoverflow.com/q/44482151/608639), [Entschlüsseln der Zeichenfolge in node.js, die in crypto.js verschlüsselt ist] (https://stackoverflow.com/ q/28359128/608639), [Was ist los mit node.js crypto dechiffer?] (https://stackoverflow.com/q/12219499/608639) – jww

Antwort

20

Ok, so Es gab einen Wechsel zu Crypto in der Umstellung von 0.8 auf 0.10 Crypto methods return Buffer objects by default, rather than binary-encoded strings

Dies bedeutet, dass der obige Code Codierungen angeben muss.

Diese vier Linien:

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

geändert zu:

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

Das ist für mich gearbeitet, aber ich bin für andere Vorschläge offen.

+1

Du hast mich so viel Zeit gerettet. Klappt wunderbar! –

+0

Ich bekomme den gleichen Fehler, aber ich benutze eine Pipeline (Übergabe der Entschlüsselungsvariable an 'Pipe' in der Datei), um Probleme mit der gesamten Datei im Speicher zu vermeiden. Irgendeine Idee, was in diesem Fall zu tun ist? – Michael

+0

Wir hatten dieses Problem mit einer Heroku-App, die in package.json kein Attribut "engines" hatte. Die Version wurde bei einer Bereitstellung aktualisiert, ohne dass wir das Problem erkannt haben. Vielen Dank! –

8

Wie Ihre Antwort besagt, funktionieren diese Funktionen jetzt mit Buffers, wenn Sie keine Codierung angeben. Das heißt, Sie wären besser dran, binary codierte Strings vollständig zu umgehen und alles als Puffer zu behandeln, bis Sie unbedingt eine Zeichenfolge für etwas benötigen. Auf diese Weise können Sie Ihre Verschlüsselungshelfer auch zum Verarbeiten von Nicht-Text-Inhalten verwenden.

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')); 
+0

Ich habe auch ein ähnliches Problem. http://stackoverflow.com/questions/32038267/getting-error-wrong-final-block-length-while-decyrpting-aes256 Werfen Sie einen Blick darauf und geben Sie Ihre wertvollen Eingaben –

0

Mein Problem war, dass die Zeichenfolge, die ich an meine Entschlüsselungsfunktion übergab, leer war. Ich habe einen Check für leere Strings eingebaut und die Nachricht nicht mehr erhalten.

decrypt: function(text){ 
       if(text.length == 0){ 
        return text; 
       } 
       return this.decipher.update(text, 'hex', 'utf8') + this.decipher.final('utf8'); 
      } 
Verwandte Themen