1

M2Cryptoを使用して、django/pythonアプリのSSO/SAMLプロバイダーから返されたXML応答に含まれる署名を検証しようとしていますが、機能しないようです。

私のXML応答は、ここの2番目の例のように見えます。

ETA:これが私の実際の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を正常に取得できます。また、発行者などを証明書から引き出すことができるため、証明書を正常にロードしていることがわかります。

signed_infoただし、署名については、渡されたXMLをハッシュし、さまざまな部分をエンコード/非エンコードし、パラメーター(SignedInfoタグ、Responseタグ、すべて)のXMLのさまざまなビットを渡してみました。 ElementTree / ElementC14N.pyを使用して、XMLが排他的に正規化されていることを確認しようとしました。これは、変換を実行する必要があることを示していますが、肯定的な結果は得られていません。

ここで何が欠けていますか?間違ったXMLに対して検証しようとしていますか?私の検証手法に何か問題がありますか?

4

2 に答える 2

2

あなたはとても近かった!signed_info を 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
于 2013-06-28T20:12:41.330 に答える