Python 3. Подписать электронной подписью на сайте

Всем привет!

На сайте есть следующая форма: Форма на сайте

Если в поле "XML запроса" загружена xml, то при нажатии на кнопку "Подписать" страница обращается к CAdES Browser Plug-in, запускается целый букет js скриптов cpro, происходит подписание xml и отправка POST запроса.

Подскажите, пожалуйста, как на Python 3 реализовать подписание xml из формы? Само подписание в данном случае ведь происходит на стороне клиента?

Как я понимаю на сервере, на котором выполняется скрипт Python должен быть установлен Крипто про. Возможно необходимо использовать библиотеку Pycades?

Возможно проще всего спарсить значение xml из формы в переменную и подписать уже это значение, а потом просто подставить в POST запрос?

Какую библиотеку лучше использовать для подписания подписью, созданную с помощью криптопровайдера Крипто про? Подойдет ли для этого signxml?

Может хотя бы теоретически объясните как такое реализовать, или может примеры подобного у кого есть?


Ответы (1 шт):

Автор решения: Roman Konoval

signxml - то что вам нужно. Вот пример с https://pypi.org/project/signxml/ :

from lxml import etree
from signxml import XMLSigner, XMLVerifier

data_to_sign = "<Test/>"
cert = open("example.pem").read()
key = open("example.key").read()
root = etree.fromstring(data_to_sign)
signed_root = XMLSigner().sign(root, key=key, cert=cert)

Он добавляет в оригинальный xml <Text/> подпись и в результате получается такой xml (привожу сокращенно):

<Test>
   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11" />
         <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
         <ds:Reference URI="">
            <ds:Transforms>
               <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
               <ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
            <ds:DigestValue>KP3ncf09YSgkeTt+i4PR+W0AMvUTo7M8gu0z15piPMc=</ds:DigestValue>
         </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>тут-значение подписи</ds:SignatureValue>
      <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>многабукаф</ds:X509Certificate>
         </ds:X509Data>
      </ds:KeyInfo>
   </ds:Signature>
</Test>

Для работы с signxml вам нужно только извлечь (конвертировать) сертификат и ключ в один из форматов, который понимает signxml, если они в другом формате у вас сейчас. Я не знаком с Крипто про, но бывают разные форматы хранения сертификатов и ключей.

→ Ссылка