2017-09-18 1 views
0

J'ai créé crypte générique et décrypter la fonctionnalité, il fonctionne très bien quand je donne une chaîne arbitraire, mais lorsque je tente de passer sha256 chaîne de hachage puis Crypto renvoie une erreur - error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block lengthNodeJS decrypt Crypto se comporte de manière incompatible

ici est le code -

let crypto = require('crypto'); 

const secret = new Buffer('1234567890abcdef71234567890abcdef1234567890abcdef1234567890abcdef', 'hex'); 
const iv = new Buffer('1234567890abcdef1234567890abcdef', 'hex'); 

const config = { 
    secret: secret, 
    iv: iv 
}; 

function encrypt(data, sec, siv) { 
    let dataBuffer = ((data instanceof Buffer)?data:Buffer.from(data)); 
    let cipher = crypto.createCipheriv('aes-256-cbc', sec, siv); 
    let crypt = cipher.update(dataBuffer); 
    crypt += cipher.final('hex'); 

    return Buffer.from(crypt, 'hex'); 
} 

function decrypt(data, sec, siv) { 
    let dataBuffer = ((data instanceof Buffer)?data:Buffer.from(data)); 
    let decipher = crypto.createDecipheriv('aes-256-cbc', sec, siv); 
    let decrypt = decipher.update(dataBuffer); 
    decrypt += decipher.final(); 

    return Buffer.from(decrypt); 
} 

function main() { 
    let test = 'asdfqwerty'; 
    let secretBytes = crypto.randomBytes(32); 
    let secretHash = Buffer.from(crypto.createHmac('sha256', config.secret).update(secretBytes).digest('hex')); 

    console.log('\nTesting test string\n==================='); 
    console.log(test); 
    a = encrypt(test, config.secret, config.iv); 
    console.log(decrypt(a, config.secret, config.iv).toString()); 

    console.log('\nTesting test string\n==================='); 
    console.log(secretHash); 

    a = encrypt(secretHash, config.secret, config.iv); 
    console.log(decrypt(a, config.secret, config.iv).toString()); 
} 

try { 
    main(); 
} catch (e) { 
    console.log(e); 
} 

Cependant, la sortie se présente comme suit -

Testing test string 
=================== 
asdfqwerty 
asdfqwerty 

Testing test string 
=================== 
<Buffer 62 36 62 62 37 39 36 65 63 36 36 36 64 32 63 61 64 34 63 61 32 32 39 66 32 35 64 38 64 30 61 39 34 66 31 39 34 38 62 33 63 66 33 38 64 37 65 62 33 39 ... > 
Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length 
    at Decipheriv.final (crypto.js:181:26) 
    at decrypt (/project/test2.js:24:23) 
    at main (/project/test2.js:43:15) 
    at Object.<anonymous> (/project/test2.js:47:3) 
    at Module._compile (module.js:573:30) 
    at Object.Module._extensions..js (module.js:584:10) 
    at Module.load (module.js:507:32) 
    at tryModuleLoad (module.js:470:12) 
    at Function.Module._load (module.js:462:3) 
    at Function.Module.runMain (module.js:609:10) 

Je ne peux pas comprendre pourquoi cela fonctionne dans le premier cas de test échoue encore sur le second cas de test.

Voici un repl.it link au code

+1

'typeof data === 'Buffer'' ne sera jamais vrai. 'typeof' ne produit que''chaîne'', ''nombre' ',' 'booléen'',' 'fonction'',' 'objet'',' 'symbole'', et'' undefined''; vous vouliez probablement dire 'Buffer.isBuffer (data)'. – Ryan

+0

Vous avez tellement raison. Merci pour cela, je pensais que je perdais la tête à propos de quelque chose qui s'avérait super basique. Je devrais utiliser 'instancesof' pour tester non' typeof'. Cependant, cela ne résout pas le problème sous-jacent puisque les méthodes cryptographiques devraient fonctionner avec des tampons ou des chaînes – JayReardon

Répondre

0

Après quelques recherches, je découvre que la question découle des attentes de la AES-256 et la taille du bloc des données à chiffrer. Les données à chiffrer ne peuvent pas être plus grandes que la taille de bloc attendue (c'est-à-dire 16 octets). Si le bloc est plus grand, crypto lancera l'erreur error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length. Lors du cryptage de grandes données avec aes-256-cbc, il est nécessaire de regrouper les données en blocs de 16 octets ou moins, de chiffrer chaque bloc, puis de regrouper chaque résultat avec une forme de séparateur.

De même, le décryptage nécessite de diviser le résultat condensé par le séparateur, de déchiffrer chaque bloc, puis de réassembler les résultats.