2012-02-27 19 views
8

Sto facendo un confronto fianco a fianco con Ruby, PHP e NodeJS per il codice seguente, ottenendo una risposta errata in NodeJS utilizzando il modulo crypto.NodeJS problema digest hmac con accenti

PHP

hash_hmac('sha256', 'text', 'á'); 

rubino

OpenSSL::HMAC.hexdigest('sha256', 'á', 'text') 

NodeJS

var signer = crypto.createHmac('sha256', 'á'); 
var expected = signer.update("text").digest('hex'); 

Sia Ruby che PHP restituiscono 34b3ba4ea7e8ff214f2f36b31c6a6d88cfbf542e0ae3b98ba6c0203330c9f55b, mentre, NodeJS restituisce 7dc85acba66d21e4394be4f8ead2a327c9f1adc64a99c710c98f60c425bd7411. Ho notato che, se provo con utf8_encode('á') in PHP, in realtà mi dà il risultato che Node si aspetta.

Sto caricando il testo accentata in nodo da un file, in questo modo:

JSON.parse(fs.readFileSync('keys.js', 'utf8')); 

Come potrei fare per cambiare il mio codice nel nodo per ottenere l'hash risultante che sia PHP e Ruby presente?

Grazie!

+0

Quale versione di nodo? Eseguendo il codice di esempio sotto il nodo v0.6.11, ottengo il risultato atteso. –

+0

Ho anche il nodo 0.6.11, su OSX 10.7 ma '7dc85acba66d21e4394be4f8ead2a327c9f1adc64a99c710c98f60c425bd7411' NON è il risultato previsto. – Roberto

+0

Certo, ricevo '34b3ba4ea7e8ff214f2f36b31c6a6d88cfbf542e0ae3b98ba6c0203330c9f55b' (su Ubuntu, il mio locale è' en_US.UTF-8'). –

risposta

13

Questo codice vi darà il risultato corretto:

var crypto = require('crypto'); 

var signer = crypto.createHmac('sha256', new Buffer('á', 'utf8')); 
var result = signer.update("text").digest('hex'); 
console.log(result); 
+0

Grazie, funziona davvero! Potresti aiutarmi a capire perché? – Roberto

+4

crypto.createHmac è un collegamento alla libreria C++. Il problema si verifica quando si converte la stringa JavaScript in C++ char *. Questo viene ripetuto per tutti i caratteri non a byte singolo. Il buffer può eseguire correttamente questa conversione. –

+0

Ah, questo ha senso. Ancora una volta, grazie! – Roberto