Hi,
I'm trying to verify a digital signature using SignedXml.CheckSignature and the rsa-sha256 algorithm. No matter what I try it keeps returning false.
I suspect that either the certificate, or the message is incorrect, but because it's not my certificate and a response message I can't be sure. When I sign and verify a message of my own it returns true.
What I'm trying to do is to activate the SignedXmlDebugLog (System.Security.Cryptography.Xml.SignedXmlDebugLog), because I think that would provide me with the information I need.
Now there's the problem. This msdn thread is the only reference I could find of the existence of this log, let alone how to enable it.
Can anyone help me / point me in the right direction how to enable this SignedXmlDebugLog / trace?Any help will be much appreciated!
Here's my C# code, I'm using VS2012 and .NET4.5
Reference:
Sign XML Documents with digital signature
Verify digital signatures of XML documents
Using receipts to verify purchases (Verify SHA256)
using System; using System.IO; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Text; using System.Xml; using System.Xml.Linq; namespace Certificate_test { public sealed class RSAPKCS1SHA256SignatureDescription : SignatureDescription { public RSAPKCS1SHA256SignatureDescription() { base.KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName; base.DigestAlgorithm = typeof(SHA256Managed).FullName; base.FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName; base.DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName; } public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key) { if (key == null) { throw new ArgumentNullException("key"); } RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key); deformatter.SetHashAlgorithm("SHA256"); return deformatter; } public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key) { if (key == null) { throw new ArgumentNullException("key"); } RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key); formatter.SetHashAlgorithm("SHA256"); return formatter; } } class Program { static void Main(string[] args) { X509Certificate2 public_cert = new X509Certificate2(File.ReadAllBytes(@"..\..\public.cer")); X509Certificate2 private_cert = new X509Certificate2(File.ReadAllBytes(@"..\..\private.pfx"), "test", X509KeyStorageFlags.PersistKeySet); try { XmlDocument document = new XmlDocument(); document.PreserveWhitespace = true; document.Load(@"..\..\input.xml"); PFCryptography.Sign(document, private_cert); if (!PFCryptography.Verify(document, public_cert)) { } } finally { private_cert.Reset(); public_cert.Reset(); } X509Certificate2 validate_cert = new X509Certificate2(File.ReadAllBytes(@"..\..\validate.cer")); try { XmlDocument document = new XmlDocument(); document.PreserveWhitespace = true; document.Load(@"..\..\response.xml"); if (!PFCryptography.Verify(document, validate_cert)) { } } finally { validate_cert.Reset(); } } public static class PFCryptography { public static void Sign (XmlDocument xmlDocument, X509Certificate2 certificate) { RSA key = (RSACryptoServiceProvider)certificate.PrivateKey; SignedXml signedXml = new SignedXml(xmlDocument); signedXml.SigningKey = key; Reference reference = new Reference(); reference.Uri = ""; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); KeyInfoName kin = new KeyInfoName(); kin.Value = certificate.Thumbprint; keyInfo.AddClause(kin); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true)); } public static bool Verify (XmlDocument xmlDocument, X509Certificate2 certificate) { SignedXml signedXml = new SignedXml(xmlDocument); // .NET does not support SHA256-RSA2048 signature verification by default, so register this algorithm for verification CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); signedXml.SigningKey = certificate.PublicKey.Key; XmlNodeList dsigs = xmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); if (dsigs.Count != 1) return false; signedXml.LoadXml((XmlElement)dsigs[0]); bool isValid = signedXml.CheckSignature(certificate, true); return isValid; } } } }