2012-03-28 88 views
4

我正在寫一段代碼來驗證X509證書中的簽名,並在主題行中獲得了異常消息。SignedXml.CheckSignature引發異常:值不能爲空。參數名稱:名稱

我的示例代碼

 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了未處理由用戶代碼
消息=值不能爲空。參數名稱:名稱PARAMNAME =名
源= mscorlib程序堆棧跟蹤: 在System.Security.Cryptography.CryptoConfig.CreateFromName(字符串名稱,對象[]參數)在System.Security.Cryptography.Xml.SignedXml.CheckSignedInfo (AsymmetricAlgorithm鍵) at System.Security.Cryptography.Xml.SignedXml.CheckSignature(AsymmetricAlgorithm key) at System.Security.Cryptography.Xml.SignedXml.CheckSignature(X509Certificate2 certificate,Boolean verifySignatureOnly) at MyNamespace.MyClass.MyFunction()in D: \ Projects \ MyProject \ Test.vb:line 117

Update 1 我打開.Net框架源調試,並且異常是從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無法處理它?

<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

是你發佈了完整的Me.samlResponseXml的XML嗎? AFAIK,您必須找到Signature元素並將其傳遞給LoadXml元素:signedXml.LoadXml(theSignatureElement)。類似於:http://msdn.microsoft.com/en-us/library/kd4wwa16.aspx – 2012-04-08 07:36:30

+0

感謝您的評論,這只是Xml的簽名部分。後來我想出了你的解釋。 – hardywang 2012-04-10 00:16:03

回答

1

SignedXml需要兩個步驟進行驗證。第一步是建設,在那裏你給它的文件或元素的簽名元素將被發現。第二部分是您必須通過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會話期間執行主機名驗證)。

相關問題