【问题标题】:SAML signature verification using Python/M2Crypto使用 Python/M2Crypto 进行 SAML 签名验证
【发布时间】:2012-03-31 02:04:55
【问题描述】:

我正在尝试使用 M2Crypto 验证从我的 django/python 应用程序中的 SSO/SAML 提供程序返回的 XML 响应中包含的签名,但我似乎无法让它工作。

我的 XML 响应看起来有点像第二个示例 here

预计到达时间:here's 我的实际 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 进行散列处理,对各种片段进行编码/不编码,并为 signed_info 参数(SignedInfo 标记、Response 标记、整个事情),我已经尝试使用 ElementTree/ElementC14N.py 来确保 XML 被完全规范化,正如转换所暗示的那样,但我没有得到积极的结果。

我在这里缺少什么?我是否试图针对错误的 XML 进行验证?我的验证技术有问题?

【问题讨论】:

  • 你有没有想过@Ennael?你介意看看my question吗?

标签: python m2crypto saml-2.0


【解决方案1】:

你离得太近了!您应该将已签名信息传递给 verify_update,然后将签名传递给 verify_final。

在验证签名之前,您确实需要确保您的 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

【讨论】:

  • 谢谢!有机会我会切换回这个项目并尝试一下。
  • 很抱歉对这样一个老问题/答案发表评论。这是否验证 SAML 令牌或断言未被触及或仅验证签名?我不清楚 m2crypto 是否在底层实现 HMAC,只是需要扩展 verify_update() 值?
【解决方案2】:

仅供参考,我遇到了和你一样的问题,并没有找到在 Python 中验证 XML 签名的有用软件,所以我写了一个新库: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)

【讨论】:

    猜你喜欢
    • 2012-02-03
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2010-12-26
    • 2017-04-12
    • 2015-11-09
    相关资源
    最近更新 更多