我是 C#.NET 编程的新手。在在线参考的帮助下,我编写了以下代码来验证 SAML 断言的签名(由服务器 API 生成)。
我的环境:
VS 2010 Ver4.0 Win XP SP3
SAML 断言令牌看起来像这样:*
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="idGYEv...USb8GfnqF" IssueInstant="2012-12-05T14:13:39.00Z">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://noszti...xyz.com</saml:Issuer>
<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="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>uDeAjOE/iCa6Pfz5oOjaOMtAQe4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>IGjZX...LaEMzA=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIE...cg6A==</X509Certificate>
<X509SubjectName>emailAddress=xmlsec@aleksey.com,CN=Aleksey Sanin,OU=Test Root Certificate,O=XML Security Library (http://www.aleksey.com/xmlsec),ST=California,C=US</X509SubjectName>
</X509Data>
</KeyInfo>
</Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">admin</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2012-12-05T14:19:39.00Z" Recipient=""/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2012-12-05T14:13:39.00Z" NotOnOrAfter="2012-12-05T14:19:39.00Z">
<saml:AudienceRestriction>
<saml:Audience/>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2012-12-05T14:13:39.00Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
我验证签名的代码片段:
//Load the SAMLAssertionToken in XML Document
XmlDocument xDoc = new XmlDocument();
xDoc.PreserveWhitespace = false;
xDoc.LoadXml(SAMLAssertionToken); //SAMLAssertionToken above
//Retrieve the public key from certificate available to end user
X509Certificate2 X509Cert = new X509Certificate2("D:/Schemas/X509Certificate.cer");
RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)X509Cert.PublicKey.Key;
//Signature Verification Starts. Find the Signature element
XmlNamespaceManager xMan = new XmlNamespaceManager(xDoc.NameTable);
xMan.AddNamespace("ns", "urn:oasis:names:tc:SAML:2.0:assertion");
xMan.AddNamespace("ns1", "http://www.w3.org/2000/09/xmldsig#");
XmlElement SigElm = (XmlElement)xDoc.SelectSingleNode("//ns:Assertion//ns1:Signature", xMan);
//Create SignedXml object and load signature for verification
SignedXml sig = new SignedXml(xDoc);
sig.LoadXml(SigElm);
bool verified = sig.CheckSignature(rsaKey);
if (verified)
{
Console.WriteLine("Signature verified successfully");
}
else
{
Console.WriteLine("Signature not valid");
}
在运行代码时,它会引发错误“无法为提供的签名算法创建签名描述”。在线:bool 验证 = sig.CheckSignature(rsaKey);
在调试时,签名被正确分配给 SigElm。注意:从“X509Certificate.cer”检索到的证书与签名元素中显示的证书完全相同(在 SAML 断言中)。所以它看起来像一个有效且匹配的证书。SAML 断言令牌中的证书使用私钥签名;所以我使用“X509Certificate.cer”(最终用户可用的证书)中的公钥来验证签名(在 SAML 断言中)。
我还尝试使用以下方法验证签名: bool verify = sig.CheckSignature(X509Cert, true); 但它会引发同样的错误。
我尝试了几种方法(针对此错误使用在线参考),但无法找出问题所在。
请给个建议...