Sprawdzanie poprawności podpisu SAML w Pythonie

Muszę zaimplementować uwierzytelnianie w pythonie z innej firmy przy użyciu SAML2. Przejrzałempysaml2 i okazało się, że jest to dość mylące i postanowiłem daćM2Crypto szansa po tym, jak znalazłemto pytanie przezEnnael.

Otrzymany token SAMLmożna znaleźć tutaj. Wyodrębniłem już wszystkie informacje, których potrzebujęAssertion tag (SSN użytkownika, IP i okno wygaśnięcia tokenów SAML), ale nie mogę uzyskaćverify_signature funkcja z Ennael (ipoprawiony kod zEzra Nugroho), aby zwrócić True. Próbowałem też się zmienićverify_EVP.reset_context(md='sha1') doverify_EVP.reset_context(md='sha256') ale to też nie zadziałało.

Myślę, że mój błąd musi być w części z podpisem. Co mam przekazaćverify_signature dla tej części? Czy muszę go wstępnie przetworzyć? Szukałem tagu Transform, ale nie wiem, gdzie dalej szukać.

Każda pomoc zostanie bardzo doceniona. Jeśli ktoś potrzebuje XML przed zaciemnieniem, aby przetestować i pomóc mi po prostu mnie.

EDYTOWAĆ To jest mój kod (bardzo podobny do rzeczy, z którymi się łączyłem. Główna funkcja znajduje się na dole):

def verify_signature(signed_info, cert, signature):
    from M2Crypto import EVP, RSA, X509, m2
    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)

    return verify_EVP.verify_final(signature.decode('base64'))

def decode_response(resp):
    return base64.b64decode(resp)

def get_xmldoc(xmlstring):
    return XML(xmlstring)


def get_signature(doc):
    return doc.find('{http://www.w3.org/2000/09/xmldsig#}Signature')


def get_signed_info(signature):
    signed_info = signature.find(
        '{http://www.w3.org/2000/09/xmldsig#}SignedInfo')
    signed_info_str = tostring(signed_info)
    # return parse(StringIO(signed_info_str))
    return signed_info_str


def get_cert(signature):
    ns = '{http://www.w3.org/2000/09/xmldsig#}'
    keyinfo = signature.find('{}KeyInfo'.format(ns))
    keydata = keyinfo.find('{}X509Data'.format(ns))
    certelem = keydata.find('{}X509Certificate'.format(ns))
    return certelem.text


def get_signature_value(signature):
    return signature.find(
        '{http://www.w3.org/2000/09/xmldsig#}SignatureValue').text

def parse_saml(saml):
    dec_resp = decode_response(saml)
    xml = get_xmldoc(dec_resp)

    signature = get_signature(xml)
    signed_info = get_signed_info(signature)
    cert = get_cert(signature)
    signature_value = get_signature_value(signature)

    is_valid = verify_signature(signed_info, cert, signature_value)

AKTUALIZACJA: Czy to możliwe, że potrzebuję więcej informacji od zewnętrznego dostawcy uwierzytelniania? Czy do tego potrzebuję klucza prywatnego?

questionAnswers(2)

yourAnswerToTheQuestion