Node js与Python中单向sha256哈希的比较

问题描述 投票:0回答:3

我有以下Python版本的代码:

import hashlib
msg = 'abc'
print msg
sha256_hash = hashlib.sha256()
sha256_hash.update(msg)
hash_digest = sha256_hash.digest()
print hash_digest

和相应的Node js版本:

var crypto= require('crypto');
var msg = 'abc';
var shasum = crypto.createHash('sha256').update(msg);
var hashDigest = shasum.digest();
console.log(hashDigest);

但是,两者的二进制输出略有偏差:

  • 节点: x AA@ ] “# a z a
  • 的Python:XAA @]“#氮杂

尽管两个库之间的十六进制表示是正确的。我在这里做错了吗?

python node.js cryptography cryptojs hashlib
3个回答
3
投票

TL;DR

您的节点代码正在尝试将散列结果解析为utf8并失败。


不同之处在于语言如何处理二进制数据和字符串类型。在考虑最终二进制输出时,您的示例都输出相同的值。让我们举例说明两个示例的输出,以十六进制表示:

ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

在Python中:

'\xbax\x16\xbf\x8f\x01\xcf\xeaAA@\xde]\xae"#\xb0\x03a\xa3\x96\x17z\x9c\xb4\x10\xffa\xf2\x00\x15\xad'

饮酒,因为:

<SlowBuffer ba 78 16 bf 8f 01 cf ea 41 41 40 de 5d ae 22 23 b0 03 61 a3 96 17 7a 9c b4 10 ff 61 f2 00 15 ad>

在这种情况下,要注意的核心是Python中的结果作为字符串返回。在Python中,字符串只是字符(0-255)值的数组。然而,Node中的值存储为Buffer,它实际上也表示一个值数组(0-255)。这是关键的不同之处。 Node不返回字符串,因为Node中的字符串不是单字节字符数组,而是UTF-16代码单元数组。 Python使用由u''指定的单独字符串类来支持Unicode。

然后比较打印输出的示例,缩短可读性

print '\xbax\x16\xbf\x8f\x01\xcf\xeaAA'

VS

console.log('' + 
    new Buffer([0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41]))

Python代码说,将这个字节数组写入终端。然而,第二个说明了一些非常不同的东西,将这个字节数组转换为字符串,然后将该字符串写入终端。但缓冲区是二进制数据,而不是UTF-8编码数据,因此无法将数据解码为字符串,从而导致结果出现乱码。如果您希望直接将二进制值作为终端中的实际解码值进行比较,则需要提供两种语言的等效指令。

print '\xbax\x16\xbf\x8f\x01\xcf\xeaAA'

VS

process.stdout.write(
    new Buffer([0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41]))

在这种情况下,process.stdout.write是一种将二进制值写入终端而不是字符串的方法。

实际上,你应该将哈希值比作十六进制,因为它已经是二进制值的字符串表示,并且比不正确解码的unicode字符更容易阅读。


2
投票

它适合我。

Python 2.7.3:

Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> msg = 'abc'
>>> sha256_hash = hashlib.sha256()
>>> sha256_hash.update(msg)
>>> hash_digest = sha256_hash.hexdigest()
>>> print hash_digest
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
>>>

所以v0.10.30:

> crypto.createHash('sha256').update('abc').digest('hex')
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'

两个十六进制字符串匹


0
投票

我有类似的情况将python hmac256函数转换为它的Node.js等价物

 def HmacSha256(key, sign):
        return hmac.new(key, sign, hashlib.sha256).digest()

 hash = HmacSha256("\0"*32, rawMsg)
 print hash

上面代码段的示例输出。

python test.py sasa
_��"/���q���h�u$�k�w�)R]n�mf�

这是散列后得到的字节的字符串表示其Nodejs等效就像这样简单

function HmacSha256(key, sign){
    return crypto
      .createHmac("sha256", key)
      .update(sign)
      .digest()
  }

const hash = HmacSha256("\0".repeat(32), rawMsg).toString()
    console.log(hash)

上面的nodejs片段的示例输出

node test.js sasa
_��"/���q���h�u$�k�w�)R]n�mf�

注意输出是相同的。我所要做的就是将HmacSha256("\0".repeat(32), rawMsg)中返回的Buffer数组转换为string。我正在使用Node v8.11.2Python 2.7.15rc1

© www.soinside.com 2019 - 2024. All rights reserved.