2 Вопрос: Hash 512 дает другие результаты в Python, чем в PHP

вопрос создан в Wed, Apr 10, 2019 12:00 AM

Я пытаюсь подключиться к API Shopwedo в Python. 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

КОД ПИТОНА

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
    
0
  1. Я проверил код python по онлайн-генератору sha512, и они совпадают. Пожалуйста, обновите ваш вопрос выводом из кода PHP, если вы добавите print($hash_preparation)
    2019-04-10 10: 44: 43Z
  2. Вы используете функцию encode() в строке ввода. Попробуйте $token = hash_hmac('sha512', utf8_encode ($hash_preparation), '');, если результаты теперь те же.
    2019-04-10 10: 58: 47Z
  3. В отличие от массивов PHP, диктанты Python не упорядочены, поэтому порядок, в котором вы join значений, не определен.
    2019-04-10 12: 30: 58Z
2 ответа                              2                         

Я предлагаю вам изучить модуль hmac Питона , чтобы достичь своей цели. находясь в поиске; Функция Pythons hmac.new(...).digest() более тесно связана с PHP 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-дикты не сортируются, поэтому вы можете иметь непредсказуемый порядок значений при переборе данных, которые вы хотите хешировать /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'

Как видите, теперь вы получаете тот же вывод hash /hmac, что и в своей версии PHP (см. код в вопросе).

    

1
2019-04-10 13: 31: 59Z

Я не думаю, что ваши функции для создания хэша эквивалентны. Вот простой тест, чтобы показать это, просто вычисляя хеш короткой строки.

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), то вы не используете эквивалентные функции.

    

- 2
2019-04-10 12: 56: 25Z
  1. Любой комментарий о причинах понижения?
    2019-04-10 12: 59: 48Z
  2. Простой хэш SHA и HMAC - это очень разные алгоритмы.
    2019-04-10 13: 13: 55Z
  3. @ deceze А, хорошо. После небольшого прочтения теперь я понимаю, что вы имеете в виду.
    2019-04-10 13: 33: 33Z
источник размещен Вот