Différents hachages SHA1 pour des valeurs identiques sur le serveur et le client

Sur le client, j’utilise Rusha, que j’ai mis dans un wrapper:

function cSHA1(m){ return (new Rusha).digest(m); } 

Sur le serveur, j’utilise le module de crypto natif de Node,

 function sSHA1(m){ var h = crypto.createHash('sha1'); h.update(m); return h.digest('hex'); } 

Essayons:

 cSHA1('foo') "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" sSHA1('foo') '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' cSHA1('bar') "62cdb7020ff920e5aa642c3d4066950dd1f01f4d" sSHA1('bar') '62cdb7020ff920e5aa642c3d4066950dd1f01f4d' 

Jusqu’ici tout va bien.

Maintenant, jetons-leur une balle courbe …

 cSHA1(Ssortingng.fromCharCode(10047)) "5bab61eb53176449e25c2c82f172b82cb13ffb9d" sSHA1(Ssortingng.fromCharCode(10047)) '5bab61eb53176449e25c2c82f172b82cb13ffb9d' 

OK bien.

J’ai une ficelle, et la façon dont je l’ai eu ne devrait pas avoir d’importance, et c’est une longue histoire, de toute façon, mais:

 s.split('').map(function(c){ return c.charCodeAt(); }) 

donne exactement le même résultat aux deux endroits:

 [58, 34, 10047, 32, 79] 

Maintenant, allons-y:

 s ":"✿ O" cSHA1(s) "a199372c8471f35d14955d6abfae4ab12cacf4fb" s ':"? O' sSHA1(s) 'fc67b1e4ceb3e57e5d9f601ef4ef10c347eb62e6' 

Cela m’a causé pas mal de chagrin; que se passe-t-il?

J’ai rencontré le même problème avec le caractère de tréma allemand lors de la comparaison de hachages SHA1 de PHP sha1 et Rusha.

La raison en est simple: certains imbéciles ont décidé que les chaînes Javascript sont UTF16 – et PHP ne se soucie pas de l’encodage, il prend juste ce qui est là. Ainsi, si vous fournissez à PHP un code json_decode (“\ u00e4”), il se transformera en une chaîne de 2 octets 0xc3 0xa4 (UTF8).

À la place, JS créera un seul octet UTF16 (0xE4) – et le manuel de Rusha indique explicitement que tous les points de code doivent être inférieurs à 256 .

Pour vous aider, utilisez la bibliothèque UTF18 à 8 à l’ adresse http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt comme sha.digest(utf16to8("\u00e4")) . Cela alimentera les codes corrects rusha.