Добавлять в саму форму цифровую подпись нет смысла - злоумышленник может добавить свою подпись, а потом на нужный адрес отправить запрос с подписью составленной им же. То есть надо как-то сохранять ключ во вьюхе, не отображая пользователю, и в то же время надо его как-то отправить в форме на Яндекс.Деньги. Изначально схема такая: форма заказ отправляет данные на Яндекс, но AJAX-скриптом попутно досылает и на мое представление, чтобы зарегистрировать заказ заранее. Для чего? ЧТобы потом, когда придет уведомление, сверять сумму, получателя и, собственно, цифровую подпись.
Что делать?
Почитайте внимательно API Яндекса. Запросы на оплату подписываются и уже уходят с верификацией и так.
От чего вы хотите защититься?
Что злоумышленник оплатит вам (а ведь он все равно оплатит), но в качестве адреса укажет свой?
Это проблема клиента - нефига столько вирусни заводить, что она свободно пасется в платежных системах от имени пользователя. Если у него есть такое уже - то денег в Яндексе уже нет.
В {{form.as_p}} просто контактные данные: имя, место проживания, почта и так далее. Что касается полей, добавленных вне джанговской формы, есть и тип оплаты, и сумма, и адресат платежа. То есть пользователь может подменить все из указанного и даже отправить платеж себе, достаточно исправить строки в форме.
Я не знаю, что делать. Не добавлять эти данные нельзя, т.к. они нужны для запроса в Яндекс через форму. Но если добавить, пользователь может их поменять. Остается проверять по приходящему уведомлению, что платеж соответствует ожидаемому. Но нужен ведь идентификатор заказа, а если его добавить прямо в форму, мошенник сможет одним запросом создавать левый заказ с нужным ключом, а вторым, на ссылку с вьюхой проверки - посылать уведомление с сочиненным им же ключом.
Полагаю, надо почитать, как взаимодействовать с этим самым sha1_hash в уведомлении Яндекса, потому что я в нем вообще ничего не понял.
И пришел к выводу, что надо расшифровывать sha1_hash, чтобы уже оттуда смотреть данные о платеже. Вот только чем расшифровывать, не понял - в hashlib есть sha1, я с ним работал так:
a = sha1()
a.update('p2p-incoming&1234567&300.00&643&2011-07-01T09:00:00.000+04:00&41001XXXXXXXX&false&01234567890ABCDEF01234567890&'.encode('utf-8'))
test = a.digest()
print(test)
with open('test.txt', 'w') as inf:
inf.write(str(test))
input()
Результата не дало - на выходе белиберда:
b'\t\n\x8e~\xbbi\x82\xa7\xadv\xf4\xc0\xf0\xfaVe\xd7A\xaa\xfa'
А должно быть:
a2ee4a9195f4a90e893cff4f62eeba0b662321f9
sim3x: да, упустил из внимания, что это именно hex-кодирование надо. Всего-то поменял на test = a.hexdigest() - и все перекодировалось как надо.
Я знаю, что знаю мало, так что уже взялся за один видеокурс по основам информационной безопасности.
Так, ладно, с расшифровкой разобрался, но как все-таки избежать подделки суммы? Пользователь ведь все еще может переписать 3000 на 50, и Яндекс не среагирует: сказано принимать из формы - он принимает. Получается, при создании записи заказа в админке придется ориентироваться не на форму, а на подсчеты внутри представления (пересчитать корзину внутри обработчика формы и записать уже это значение).
Я в правильном направлении мыслю?
И правда, только сейчас после дальнейшего гугления начал подозревать, что работает только в одну сторону. Тогда, думаю, надо не напрямую расшифровывать, а составлять на своем стороне sha1 в представлении, принимающем уведомление, и там уже сравнивать с тем, что пришло.
На этот раз верно всё?