为了账号安全,请及时绑定邮箱和手机立即绑定

Hash 512 在 Python 中与在 PHP 中给出的结果不同

Hash 512 在 Python 中与在 PHP 中给出的结果不同

慕侠2389804 2022-01-05 19:54:43
我正在尝试使用 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 代码返回:b0d45466aa68db7df247d858094f88010b7c58820538309fffe28a42458a6ce4b6b2d48b1c5b9d40492851db075af9d86b2e1c81c4a6960d3dfb4616bccb617a蟒蛇代码import hashlibparams={'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 代码返回:34480ef855ff09d743ff5931ff39851ee4031e470c0fddb7e7ba6a1c9a8a5145bfbcd020c11220287f2747f28f48d77893fff4f8dcce82ab54e70c67f172bab9
查看完整描述

2 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

我建议你查看 Pythonshmac模块来实现你想要的;Pythons 函数hmac.new(...).digest()与 PHP 的关系hash_hmac()比您尝试使用的更密切hashlib.sha512()。


这是一个简单的字符串测试,用于显示它们返回相同的输出:


蟒蛇 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 dict 未排序的事实,因此在迭代要散列/hmac 的数据时,您可能会遇到不可预测的值顺序。


我建议您定义一个具有所需键顺序的列表(或完全跳过字典),可能是这样的:


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 输出(请参阅问题中的代码)。


查看完整回答
反对 回复 2022-01-05
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

我不认为您制作哈希的函数是等效的。这是一个简单的测试来证明这一点,只是计算一个短字符串的哈希值。


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 知之甚少),那么您没有使用等效的函数。


查看完整回答
反对 回复 2022-01-05
  • 2 回答
  • 0 关注
  • 222 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信