简体   繁体   English

服务器和客户端上具有相同值的不同SHA1散列

[英]Differing SHA1 hashes for identical values on the server and the client

On the client I'm using Rusha, which I've put into a wrapper: 在客户端上,我使用的是Rusha,已将其放入包装器中:

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

On the server I'm using Node's native crypto module, 在服务器上,我正在使用Node的本机crypto模块,

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

Let's try it: 让我们尝试一下:

cSHA1('foo')
"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"

sSHA1('foo')
'0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'

cSHA1('bar')
"62cdb7020ff920e5aa642c3d4066950dd1f01f4d"

sSHA1('bar')
'62cdb7020ff920e5aa642c3d4066950dd1f01f4d'

So far, so good. 到现在为止还挺好。

Now let's throw them a curveball... 现在让我们给他们扔一个曲线球...

cSHA1(String.fromCharCode(10047))
"5bab61eb53176449e25c2c82f172b82cb13ffb9d"

sSHA1(String.fromCharCode(10047))
'5bab61eb53176449e25c2c82f172b82cb13ffb9d'

Ok, fine. 好的。

I have a string, and it shouldn't be important how I got it, and it's a long story, anyway, but: 我有一个字符串,我如何获取它并不重要,无论如何这是一个漫长的故事,但是:

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

yields the exact same result in both places: 在两个地方产生完全相同的结果:

[58, 34, 10047, 32, 79]

Now, let's hash it: 现在,让我们对其进行哈希处理:

s
":"✿ O"

cSHA1(s)
"a199372c8471f35d14955d6abfae4ab12cacf4fb"

s
':"? O'
sSHA1(s)
'fc67b1e4ceb3e57e5d9f601ef4ef10c347eb62e6'

This has caused me a fair bit of grief; 这使我有些悲痛。 what the hell? 搞什么鬼?

I have run into the same problem with the German Umlaut character when comparing SHA1 hashes of PHPs sha1 and Rusha. 在比较PHPs sha1和Rusha的SHA1哈希值时,我遇到了德国Umlaut字符的相同问题。

The reason is simple: some stoned fool decided Javascript strings are UTF16 - and PHP doesn't give a sh*t about encoding, it just takes what is there. 原因很简单:一些愚蠢的人断定Javascript字符串是UTF16-PHP并没有给出编码的问题,它只是占用了其中的内容。 So, if you supply PHP a json_decode("\ä"), it will turn this into a 2-byte string 0xc3 0xa4 (UTF8). 因此,如果您为PHP提供json_decode(“ \\ u00e4”),它将把它变成2字节的字符串0xc3 0xa4(UTF8)。

JS instead will make a single UTF16 byte out of this (0xE4) - and Rusha's manual explicitly says all codepoints must be below 256 . JS会从(0xE4)中提取单个UTF16字节-Rusha的手册明确指出所有代码点必须低于256

To help yourself, use the UTF18-to-8 library at http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt like sha.digest(utf16to8("\ä")) . 为了帮助自己,请使用http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt中的UTF18-to-8库,如sha.digest(utf16to8("\ä")) This will feed rusha correct codepoints. 这将为rusha提供正确的代码点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM