Hash 512在Python中提供的结果与PHP不同

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

我正在尝试使用Python连接到Shopwedo API。 https://admin.shopwedo.com/developer/

除了哈希之外,一切都很顺利。下面是PHP和Python中的示例脚本。相同字符串的散列会返回不同的最终结果。

PHP代码

/** * Prepare credentials: */ 
$credentials = array(    
 'id' => 1234,     
'key' => "HelloTest",     
'timestamp' => 1554888606,    
 'salt' => 'diego' );

/** * Generate token by combining credentials: */ 
$hash_preparation = implode('', array_values($credentials));
$token = hash_hmac('sha512', $hash_preparation, '');

print($token);

这个PHP代码返回:

b0d45466aa68db7df247d858094f88010b7c58820538309fff
e28a42458a6ce4b6b2d48b1c5b9d40492851db075af9d86b2e
1c81c4a6960d3dfb4616bccb617a

PYTHON代码

import hashlib

params={'shopid':1234,
        'apikey': "HelloTest",
        'timestamp':1554888606,
        'salt': "diego"}

tosign = "".join([str(params[i]) for i in params] )
token = hashlib.sha512(tosign.encode()).hexdigest()

print(token)

这个Python代码返回:

34480ef855ff09d743ff5931ff39851ee4031e470c0fddb7e7
ba6a1c9a8a5145bfbcd020c11220287f2747f28f48d77893ff
f4f8dcce82ab54e70c67f172bab9
php python hash sha512
2个回答
1
投票

我建议你看看Pythons hmac module来实现你想要的;蟒蛇函数hmac.new(...).digest()与PHPs hash_hmac()关系比你用hashlib.sha512()尝试的更密切。

这是一个简单的字符串测试,表明它们返回相同的输出:

Python 3.6

>>> import hmac
>>> hmac.new(''.encode(), 'Hello'.encode(), 'sha512').hexdigest()
'b31d977587ea18dd68bb795d1b79d59ebf8b9aff7648f4f441fc421b05cc2486efe9d5b413ea6828addbca0f60294169ae56435408e0063b5f183afb64f51a5d'

PHP 7.3(在线测试http://www.writephponline.com/

print(hash_hmac('sha512', 'Hello', ''));
b31d977587ea18dd68bb795d1b79d59ebf8b9aff7648f4f441fc421b05cc2486efe9d5b413ea6828addbca0f60294169ae56435408e0063b5f183afb64f51a5d

print(hash_hmac('sha512', utf8_encode('Hello'), ''));
b31d977587ea18dd68bb795d1b79d59ebf8b9aff7648f4f441fc421b05cc2486efe9d5b413ea6828addbca0f60294169ae56435408e0063b5f183afb64f51a5d

现在,正如用户@deceze在注释中指出的那样,您需要考虑Python dicts未排序的事实,因此在迭代您想要哈希/ hmac的数据时,您可能会有不可预测的值顺序。

我建议你定义一个列表,其中包含所需的键顺序(或完全跳过dict),也许是这样的:

import hmac

params={
    'shopid': 1234,
    'apikey': "HelloTest",
    'timestamp': 1554888606,
    'salt': "diego",
}
key_list = ['shopid', 'apikey', 'timestamp', 'salt']
tosign = ''.join(str(params[k]) for k in key_list)
# '1234HelloTest1554888606diego'

token = hmac.new(''.encode(), tosign.encode(), 'sha512').hexdigest()
print(token)
# 'b0d45466aa68db7df247d858094f88010b7c58820538309fffe28a42458a6ce4b6b2d48b1c5b9d40492851db075af9d86b2e1c81c4a6960d3dfb4616bccb617a'

如您所见,现在您获得与PHP版本相同的哈希/ hmac输出(请参阅问题中的代码)。


-2
投票

我不认为你的函数使哈希是等价的。这是一个简单的测试,表明只计算短字符串的哈希值。

Python 3.6(在我的Ubuntu机器上)

>>> import hashlib
>>> hashlib.sha512('Hello'.encode()).hexdigest()
'3615f80c9d293ed7402687f94b22d58e529b8cc7916f8fac7fddf7fbd5af4cf777d3d795a7a00a16bf7e7f3fb9561ee9baae480da9fe7a18769e71886b03f315'

Python 2.7(在线测试https://repl.it/languages/python

>>> import hashlib
>>> hashlib.sha512('Hello'.encode()).hexdigest()
'3615f80c9d293ed7402687f94b22d58e529b8cc7916f8fac7fddf7fbd5af4cf777d3d795a7a00a16bf7e7f3fb9561ee9baae480da9fe7a18769e71886b03f315'

PHP 7.3(在线测试http://www.writephponline.com/

print(hash_hmac('sha512', 'Hello', ''));
b31d977587ea18dd68bb795d1b79d59ebf8b9aff7648f4f441fc421b05cc2486efe9d5b413ea6828addbca0f60294169ae56435408e0063b5f183afb64f51a5d

print(hash_hmac('sha512', utf8_encode('Hello'), ''));
b31d977587ea18dd68bb795d1b79d59ebf8b9aff7648f4f441fc421b05cc2486efe9d5b413ea6828addbca0f60294169ae56435408e0063b5f183afb64f51a5d

如您所见,两个Python版本都返回相同的哈希,但PHP是不同的。如果我的PHP代码是正确的(我对PHP知之甚少),那么你没有使用等效的函数。

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