SignedXml.CheckSignature генерирует исключение: значение не может быть нулевым. Имя параметра: имя
Я пишу кусок кода для проверки подписи в Xml из сертификата X509 и получил сообщение об исключении в строке темы.
Мой пример кода
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-я строка кода). Я успешно заполнил signXml (2-я строка кода).
Исключение выдает, когда я звоню signedXml.CheckSignature(cert, True)
функция. Сообщение очень неясно:
Значение не может быть нулевым.
Имя параметра: имя
Любая подсказка, что здесь не так?
Стеки вызовов:
System.ArgumentNullException не было обработано кодом пользователя
Сообщение = значение не может быть нулевым. Имя параметра: имя ParamName= имя
Source=mscorlib StackTrace: в System.Security.Cryptography.CryptoConfig.CreateFromName(имя строки, объект [] args) в System.Security.Cryptography.Xml.SignedXml.CheckSignedInfo(ключ Asymmetric.lgorithm) в System.Security.Security.CheckSignature(ключ AsymmetricAlgorithm) в System.Security.Cryptography.Xml.SignedXml.CheckSignature(сертификат X509Certificate2, Boolean verifySignatureOnly) в MyNamespace.MyClass.MyFunction() в D:\Projects\MyProject.
Обновление 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 объяснение SignatureMethod по адресу http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.signedxml.signaturemethod.aspx и проверил код 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 ответ
SignedXml требует двух шагов для проверки. Шаг 1 является конструкцией, где вы даете ему документ или элемент, в котором будут найдены подписанные элементы. Вторая часть заключается в том, что вы должны загрузить элемент Signature (который мог прийти из другого документа) с помощью метода LoadXml.
Чтобы взять пример со страницы MSDN SignedXml, но измените его для сертификатов:
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).