Проверка подписи SAML с использованием Python / M2Crypto - PullRequest
1 голос
/ 14 марта 2012

Я пытаюсь использовать M2Crypto для проверки подписи, содержащейся в ответе XML, возвращенном моим провайдером SSO / SAML, в моем приложении django / python, но я не могу заставить его работать.

Мой XML-ответ выглядит как второй пример здесь .

ETA: И здесь вставка моего настоящего XML.

Я использую некоторый код, подобный этому, для попытки проверки:

def verify_signature(signed_info, cert, signature):
    from M2Crypto import EVP, RSA, X509

    x509 = X509.load_cert_string(base64.decodestring(cert), X509.FORMAT_DER)
    pubkey = x509.get_pubkey().get_rsa()
    verify_EVP = EVP.PKey()
    verify_EVP.assign_rsa(pubkey)
    verify_EVP.reset_context(md='sha1')
    verify_EVP.verify_init()

    verify_EVP.verify_update(signature.decode('base64'))
    result = verify_EVP.verify_final(signed_info)

    return result

Я могу успешно получить NameID из ответа, и я знаю, что я успешно загружаю сертификат, потому что я могувытащить из него эмитента и т. д.

Что касается сигнатуры, я попытался хэшировать переданный в XML, кодировать / не кодировать различные фрагменты и передавать различные биты XML для *Параметр 1018 * (тег SignedInfo, тег Response и т. Д.), И я попытался использовать ElementTree / ElementC14N.py , чтобы убедиться, что XML-код исключительно канонизирован, как следует из преобразования,но я не получаю порезультат.

Что мне здесь не хватает?Я пытаюсь проверить не тот XML?Что-то не так с моей техникой проверки?

Ответы [ 2 ]

2 голосов
/ 29 июня 2013

Вы были так близко! Вы должны перейти к verify_update signature_info, а затем verify_final передать подпись.

Перед проверкой подписи необходимо убедиться, что ваша подписанная_инфо правильно канонизирована.

Вот правильный метод:

def verify_signature(signed_info, cert, signature):
    from M2Crypto import EVP, RSA, X509

    x509 = X509.load_cert_string(base64.decodestring(cert), X509.FORMAT_DER)
    pubkey = x509.get_pubkey().get_rsa()
    verify_EVP = EVP.PKey()
    verify_EVP.assign_rsa(pubkey)
    verify_EVP.reset_context(md='sha1')
    verify_EVP.verify_init()

    verify_EVP.verify_update(signed_info)
    result = verify_EVP.verify_final(signature.decode('base64'))

    return result
1 голос
/ 03 октября 2014

К вашему сведению, я столкнулся с той же проблемой, что и вы, и не нашел никакого полезного программного обеспечения для проверки подписей XML в Python, поэтому я написал новую библиотеку: https://github.com/kislyuk/signxml.

from lxml import etree
from signxml import xmldsig

with open("saml2_idp_metadata.xml", "rb") as fh:
    cert = etree.parse(fh).find("//ds:X509Certificate").text

root = ElementTree.fromstring(signature_data)
xmldsig(root).verify(x509_cert=cert)
...