在服务器和客户端上使用相同的SHA1哈希值 [英] Differing SHA1 hashes for identical values on the server and the client

查看:275
本文介绍了在服务器和客户端上使用相同的SHA1哈希值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 函数cSHA1(m)在客户端我使用的是Rusha, {
return(new Rusha).digest(m);

$ / code>

在服务器上,我使用Node的本地加密模块,

 函数sSHA1(m){
var h = crypto.createHash( 'SHA1');
h.update(m);
return h.digest('hex');
}

让我们试试看:

  cSHA1('foo')
0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

sSHA1('foo')
'0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'

cSHA1('bar')
62cdb7020ff920e5aa642c3d4066950dd1f01f4d

sSHA1('bar')
'62cdb7020ff920e5aa642c3d4066950dd1f01f4d'

到目前为止,这么好。



现在让我们将它们引入曲线球...

  cSHA1(String.fromCharCode(10047))
5bab61eb53176449e25c2c82f172b82cb13ffb9d

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

好的,



我有一个字符串,它的重要性应该不是很重要,无论如何,这是一个很长的故事,但是:

<$ (c){
return c.charCodeAt();
})

收益率这两个地方的结果完全相同:

  [58,34,10047,32,79] 
code>

现在,让我们对它进行哈希:

 :✿O

cSHA1(s)
a199372c8471f35d14955d6abfae4ab12cacf4fb

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

这使我一点点悲伤;到底是什么东西?

解决方案

当比较shas1和shashha的SHA1哈希值时,我遇到了与德语变音符相同的问题。
$ b

原因很简单:一些扔石头的傻瓜决定Javascript字符串是UTF16 - 而PHP没有提供关于编码的sh * t,它只是需要什么。因此,如果您向PHP提供了一个json_decode(\\\ä),它会将它变成一个2字节的字符串0xc3 0xa4(UTF8)。

从这个(0xE4)中创建一个UTF16字节 - 并且Rusha的手册明确地说所有codepoints必须低于256

为了帮助你自己,请使用 http:// www。utf18-to-8 library。 onicos.com/staff/iz/amuse/javascript/expert/utf.txt ,例如 sha.digest(utf16to8(\\\ä))。这将提供rusha正确的代码点。


On the client I'm using Rusha, which I've put into a wrapper:

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

On the server I'm using Node's native crypto module,

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.

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. So, if you supply PHP a json_decode("\u00e4"), it will turn this into a 2-byte string 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.

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("\u00e4")). This will feed rusha correct codepoints.

这篇关于在服务器和客户端上使用相同的SHA1哈希值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆