sortarage
@sortarage
Я тучка-тучка-тучка, я вовсе не медведь

Как правильно проверять base64/md5 подпись на Python (пример на PHP)?

Что необходимо: проверять валидность подписи платежа, который приходит с платежного сервиса с помощью Python 3.

Пример на PHP:
unset($dataSet['ik_sign']); удаляем из данных строку подписи
ksort($dataSet, SORT_STRING); // сортируем по ключам в алфавитном порядке элементы массива
array_push($dataSet, $key); // добавляем в конец массива "секретный ключ"
$signString = implode(':', $dataSet); // конкатенируем значения через символ ":"
$sign = base64_encode(md5($signString, true)); // берем MD5 хэш в бинарном виде по
сформированной строке и кодируем в BASE64
return $sign; // возвращаем результат

Моя реализация на Python:
# Сортирую ключи словаря по алфавиту, собираю значения в список
# Игнорирую ik_sign
data = [x[-1] for x in sorted(request_data.items()) if x[0] != 'ik_sign']

# Добавляю секретный ключ
data.append(secret_key)

# Объединяю все данные списка через :
data_string = ':'.join(data)

# Подготавливаю md5
m = hashlib.md5()
m.update(data_string.encode('utf-8'))

# Кодираю в base64
result = base64.b64encode(m.hexdigest().encode('utf-8'))

На выходе получаю 44 символа вместо 24, то есть, вообще ни на что не похоже :)
Вопрос: что я делаю не так?

Пример данных:
request_data = dict([('ik_desc', 'Event Description'), ('ik_co_prs_id', '302460491953'), ('ik_ps_price', '103'), ('ik_cur', 'UAH'), ('ik_pm_no', 'ID_4233'), ('ik_inv_id', '105225278'), ('ik_inv_prc', '2018-08-07 17:18:37'), ('ik_co_rfn', '100'), ('ik_trn_id', ''), ('ik_x_keyword', 'а яблоки на снегу'), ('ik_am', '100'), ('ik_inv_st', 'success'), ('ik_x_waka_id', '645654'), ('ik_pw_via', 'test_interkassa_test_xts'), ('ik_x_order_id', '123'), ('ik_inv_crt', '2018-08-07 17:18:37'), ('ik_sign', '9woX5fHhD8E8msboHWE4mw=='), ('ik_co_id', '5b5b1fec3b1eaf330d8b4568')])
secret_key = 'tykv1bZ6yHup8BDX'
result = '9woX5fHhD8E8msboHWE4mw=='
  • Вопрос задан
  • 582 просмотра
Решения вопроса 1
skobkin
@skobkin
Гентушник, разработчик на PHP и Symfony.
https://stackoverflow.com/a/5297483 ?

Судя по всему, разница в том, что вы в PHP кодируете бинарный результат MD5, а в Python - HEX-запись. Вам, полагаю, нужен просто m.digest().

Такого же результата мы можем добиться в PHP:
md5('test', true);
// b"\tÅk═F!Ës╩ÌNâ&'┤÷"
base64_encode(md5('test', true))
// "CY9rzUYh03PK3k6DJie09g=="
strlen(base64_encode(md5('test', true)))
// 24
strlen(base64_encode(md5('test')))
// 44
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы