A
A
Alexander Lebedev2018-08-07 17:55:19
Python
Alexander Lebedev, 2018-08-07 17:55:19

How to validate base64/md5 signature in Python (PHP example)?

What you need: check the validity of the payment signature that comes from the payment service using Python 3.
PHP example:

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; // возвращаем результат

My implementation in 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'))

At the output I get 44 characters instead of 24, that is, it doesn’t look like anything at all :)
Question: what am I doing wrong?
Sample data:
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=='

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Skobkin, 2018-08-07
@sortarage

https://stackoverflow.com/a/5297483 ?
Apparently, the difference is that in PHP you encode a binary MD5 result, and in Python you encode a HEX record. I think you just need m.digest().
We can achieve the same result in 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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question