Проверка подписи SAML с помощью Python Flask

У меня есть веб-приложение Python Flask. Я интегрирую OKTA SAML в это приложение для аутентификации.

Я выполнил следующие шаги:

Однако проверка всегда терпит неудачу. Когда я бегу verify_signature(), всегда выдает 0.

Мой код:

def verify_signature(signed_info, cert, signature):
    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='sha256')
    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.fromstring(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 = str(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

# Main Function
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)
print is_valid # ALWAYS PRINTS 0.

person Narayan Gowraj    schedule 19.07.2016    source источник
comment
Добро пожаловать в Stack Overflow! Какие ошибки вы получаете?   -  person Andrew Myers    schedule 19.07.2016
comment
Я не получаю сообщения об ошибке. Все проходит успешно, но проверка всегда терпит неудачу. то есть: is_valid ВСЕГДА ВОЗВРАЩАЕТ НУЛЬ. У меня есть ответ SAML, подписанный sha256.   -  person Narayan Gowraj    schedule 19.07.2016


Ответы (2)


Если вы не разбираетесь в XML, спецификация XML Signature, криптографическое хеширование и открытый ключ шифрования, я настоятельно призываю вас не писать свою собственную процедуру проверки SAML.

Для некоторых конкретных примеров того, насколько сложно правильно разобрать SAML, я предлагаю прочитать "О взломе SAML: будь кем хочешь быть », который представляет собой отличный научный документ, в котором рассматриваются различные способы обхода проверки SAML. Кроме того, хорошим недавним примером того, как крупная компания неправильно проверяет SAML, является "Дорога в ад вымощена SAML Assertions ".

На высоком уровне я бы посоветовал приложить усилия для изучения особенностей установленной библиотеки проверки SAML, такой как PySAML2, чтобы вы могли извлечь выгоду из работы, проделанной другими, чтобы избежать распространенных ошибок безопасности в SAML. Для PySAML2 метод validate_signature в - хорошее место для начала.

Если после всех моих предупреждений вы все еще заинтересованы в проведении собственной проверки SAML, я предлагаю посмотреть на signxml или напрямую с помощью двоичного файла xmlsec1.

person Joël Franusic    schedule 21.07.2016

Я хотел направить вас к нашим инструкциям для приложений Python: http://developer.okta.com/docs/guides/pysaml2 Кроме того, следуйте примеру для PySAML2 здесь: https://github.com/jpf/okta-pysaml2-example У вас есть метод обработки запросов на выход из системы?

person Shradha Gaikwad    schedule 20.07.2016
comment
У меня приложение работает с pysaml2. Я также пытался выполнить проверку подписи вручную, для чего используется приведенный выше код. Но он продолжает терпеть неудачу. - person Narayan Gowraj; 21.07.2016