SignedXml.CheckSignature抛出异常:值不能为null。参数名称:名称

时间:2012-03-28 20:26:21

标签: .net x509certificate xml-signature saml-2.0

我正在编写一段代码来验证来自X509证书的Xml中的签名,并在主题行中获得异常消息。

我的示例代码

        Dim cert As X509Certificate2 = GetCertificate("Certificate Name")

        Dim signedXml As SignedXml = New SignedXml(Me.samlResponseXml)
        If (signedXml.CheckSignature(cert, True)) Then
            ' The signature is valid
        Else
            ' The signature is invalid
            Throw New ArgumentException("Invalid signature found in Saml Xml.")
        End If

我已成功从证书存储区加载证书(代码的第1行)。 我已经成功填充了signedXml(代码的第二行)。

当我调用signedXml.CheckSignature(cert, True)函数时抛出异常。这条消息非常不清楚:

  

值不能为空。
  参数名称:名称

有任何疑问,这里有什么问题?

调用堆栈:

  

System.ArgumentNullException未被用户代码
处理   Message = Value不能为null。参数名称:名称ParamName =名称
  Source = mscorlib StackTrace:          在System.Security.Cryptography.CryptoConfig.CreateFromName(String name,Object [] args)          在System.Security.Cryptography.Xml.SignedXml.CheckSignedInfo(AsymmetricAlgorithm key)          在System.Security.Cryptography.Xml.SignedXml.CheckSignature(AsymmetricAlgorithm key)          在System.Security.Cryptography.Xml.SignedXml.CheckSignature(X509Certificate2 certificate,Boolean verifySignatureOnly)          在D:\ Projects \ MyProject \ Test.vb中的MyNamespace.MyClass.MyFunction():第117行

更新1 我打开.Net Framework源代码调试,从SignedXml.CheckSignedInfo方法抛出异常,有代码行

SignatureDescription signatureDescription = CryptoConfig.CreateFromName(SignatureMethod) as SignatureDescription;

很明显,SignatureMethod是

的包装
    public string SignatureMethod  {
        get { return m_signature.SignedInfo.SignatureMethod; }
    }

m_signature.SignedInfo.SignatureMethod是空值。我再次从MSDN上读到了http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.signedxml.signaturemethod.aspx处SignatureMethod的解释,并在下面粘贴了带有签名部分的Xml代码。我有一个SignatureMethod标记,其中包含值,但为什么SignedXml无法处理它?<​​/ p>

  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="#_ea559faf-417b-407f-bdc2-bccc76dab76c">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <InclusiveNamespaces PrefixList="#default samlp saml ds xs xsi" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </Transform>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>fvQx+J90ZGKhwj8Mfhg6v/esOtI=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>Ft2mQEA3a39uRq5N94pDI8Y6B/UGLXHkZJ+/besOQmEtZoi630vBDzQfIxx5Djgg6YYeF/s67iF+KLgfvBrHxoe3E8xiqTwBigem41+PJdITlwgrOTkLo2sSdj4DaFdxeN+SCy6KfKXpDBvDyN4i/R0hBKodGwytfzK/DMeOhHU=</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>MIICBjCCAXOgAwIBAgIQ3VhOVESMV71O0q5EttLxxDAJBgUrDgMCHQUAMBwxGjAYBgNVBAMTEUlkZW50aXR5UHJvdmlkZXIxMB4XDTExMDkwMTA1MDAwMFoXDTQwMTIzMTA1MDAwMFowHDEaMBgGA1UEAxMRSWRlbnRpdHlQcm92aWRlcjEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBVhtKneTweMOgmvwO+i8AvZ5p0/PGatzLKNXVctTROcXb48u3L9JR3sVPasAFNsafq086xqaWyuFM7jAHtYHTQg/oLt+wGCKd7w/n4s0crxM3NVahDmSUPnBW9RZM2XD4pOs9DTu8aEEQGN/p01jrIMgPYhdlVsTJSg43lLyzjAgMBAAGjUTBPME0GA1UdAQRGMESAEHDoTOJwf2lSgqgCU4TXI2ShHjAcMRowGAYDVQQDExFJZGVudGl0eVByb3ZpZGVyMYIQ3VhOVESMV71O0q5EttLxxDAJBgUrDgMCHQUAA4GBAKvsy5KkU9dDNWDRW55/+s7txFfl4ZmWw45AmZYXEA90g+xzALFtWbX/QGqCOx4C0h5fB5Oco084B7gJK/uf2a8oaYvxYGwlxgRxJ9Dq5XBx5ZhOuobT8G2xVy575cbaGnFbObG6/E33Mva1gAYdw7rvGaz/dYuBeChsEIvzROYU</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>

1 个答案:

答案 0 :(得分:1)

SignedXml需要两个步骤进行验证。第1步是构造,在其中为其提供将在其中找到已签名元素的文档或元素。第二部分是你必须通过LoadXml方法加载Signature元素(可能来自不同的文档)。

the SignedXml MSDN page为例,但修改证书:

public static Boolean VerifyXmlFile(XmlElement samlResponseXml, X509Certificate2 cert)
{
    // Create a new SignedXml object and pass it the XML.
    SignedXml signedXml = new SignedXml(samlResponseXml);

    // Find the "Signature" node and create a new XmlNodeList object.
    XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");

    // TODO: Error checking.  Was it found? Were too many found?

    // Load the signature node.
    signedXml.LoadXml((XmlElement)nodeList[0]);

    // Check the signature and return the result.
    return signedXml.CheckSignature(cert, true);
}

使用SignedXml时,请注意MSDN页面上“备注”部分提出的问题。特别是,确保签名密钥适合签名内容(类似于在TLS会话期间执行主机名验证)。