2012-03-14 6 views
1

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

Мой ответ XML выглядит как второй пример here.

ETA: И here's a pastebin моего фактического 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 для параметра signed_info (тег SignedInfo, тег Response, целое вещь), и я попытался использовать ElementTree/ElementC14N.py, чтобы гарантировать, что XML исключительно канонизируется, поскольку Transform подразумевает, что это должно быть сделано, но я не получаю положительного результата.

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

+0

Вы когда-нибудь думали об этом @Ennael? Не могли бы вы взглянуть на [мой вопрос] (http://stackoverflow.com/questions/21209510/validating-saml-signature-in-python)? –

ответ

1

Вы были так близко! Вы должны передать check_update signed_info, а затем проверить подлинность.

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

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

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 
+0

Спасибо! Я вернусь к этому проекту, когда у меня появится шанс и попробую. – Ennael

1

FYI, я столкнулся с той же проблемой, как вы, и не нашел полезное программное обеспечения для проверки подлинности подписей 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) 
+0

будет работать в Windows? – digz6666

Смежные вопросы