验证在Python SAML签名 [英] Validating SAML signature in python

查看:1412
本文介绍了验证在Python SAML签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用SAML2由第三方实施蟒蛇认证。我已经看着 pysaml2 并发现这是相当混乱,并决定给 M2Crypto 的机会,我发现后,<一个href=\"http://stackoverflow.com/questions/9704919/saml-signature-verification-using-python-m2crypto\">this问题 Ennael

I need to implement authentication in python from a 3rd party by using SAML2. I have looked into pysaml2 and found that to be quite confusing, and decided to give M2Crypto a chance after I found this question by Ennael.

SAML令牌我收到可以在这里找到。我已经提取我从断言标签(用户的SSN,IP和SAML令牌过期窗口)需要的所有信息,但我不能让<$ C $从Ennael C> verify_signature 函数(和<一个href=\"http://stackoverflow.com/questions/9704919/saml-signature-verification-using-python-m2crypto/17372895#17372895\">revised从以斯拉努格罗霍)code 返回true。我也试过 verify_EVP.reset_context(MD ='SHA-1')更改为 verify_EVP.reset_context(MD ='SHA256')但是这也不能工作。

The SAML token I receive can be found here. I have already extracted all the information I need from the Assertion tag (the user's SSN, IP and the SAML tokens expiration window) but I can't get the verify_signature function from Ennael (and the revised code from Ezra Nugroho) to return True. I have also tried to change verify_EVP.reset_context(md='sha1') to verify_EVP.reset_context(md='sha256') but that didn't work either.

我觉得我的错误必须在signed_info一部分。我通过什么 verify_signature 的那部分?我一定要preprocess以任何方式?我一直在寻找进入转换标签,但不知道去哪里看太旁边。

I think my mistake must be in the signed_info part. What do I pass to verify_signature for that part? Do I have to preprocess it in any way? I have been looking into the Transform tag but don't know where too look next.

任何帮助将大大AP preciated。如果有人需要XML混淆之前测试和帮助我只是下午我。

Any help will be greatly appreciated. If someone needs the XML before the obfuscation to test and help me just PM me.

修改这是我的code(非常类似于我挂东西的主要功能是在底部。)

EDIT This is my code (very similar to the things i linked to. The main function is at the bottom):

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)

更新:是否有可能,我需要从第三方身份验证提供一些更多的信息?我是否需要任何这方面的一个私钥?

UPDATE: Is it possible I need some more information from the 3rd party authentication provider? Do I need a private key for any of this?

推荐答案

我面临同样的问题,必须开发一个模块为它:的 https://github.com/kislyuk/signxml 。我选择了只依靠PyCrypto和pyOpenSSL,因为M2Crypto是冷门,而不是维护良好的,这是从两个兼容(例如PyPy)和安全性的角度危险。我还使用LXML的规范化(C14N)。从signxml文档:

I faced the same problem, and had to develop a module for it: https://github.com/kislyuk/signxml. I chose to rely only on PyCrypto and pyOpenSSL, since M2Crypto is less popular and not well-maintained, which is a hazard from both compatibility (e.g. PyPy) and security perspectives. I also use lxml for the canonicalization (c14n). From the signxml docs:

from signxml import xmldsig

cert = open("example.pem").read()
key = open("example.key").read()
root = ElementTree.fromstring(data)
xmldsig(root).verify()

这篇关于验证在Python SAML签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆