SignedXml.CheckSignature alway return false.

谭振华 1 Reputation point
2024-08-13T04:55:39.46+00:00

Here is my code ,VerifyXmlDocumentSignature alway return false.

I checked my signedxml this site https://tools.chilkat.io/xmlDsigVerify.cshtml,my xml signed is valid.

<root><creditcard><number>19834209</number><expiry>02/02/2002</expiry></creditcard><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>ghOEPeYtAUs5Kb8VMOCIS3f2wIY=</DigestValue></Reference></SignedInfo><SignatureValue>MBp4YHs0QPWhjTALq+Vjq4ag/fzdqjSSlydDMjtHyenEW10QbzsgzbnT4pFZTAgKBZsyxdPU32qlpacDq80R19SFj+ZnwEn/qn02C4SH18AaT90rwfY1UVpZLv10bYEl6/3G//1ZWz11cS2Gmh2GsAEuKgtSnMTdkP1YSp0Zz6pn4/6kM61K3BKcEIG5WDhnAQzIJrTmx/ggq8v9vjcUKABnkU/HTQIoYculk5UARaKyDdOz+EwkXwM1sVSXdx/ZMPxPxWIKRX3yJZYaZYEfoH4EFKfN6L0845GcB6zZt9lwTupGzj8tfwl7YiNS2iIdIL5iISuY+/b2UcHW8Fj0hQ==</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIFPjCCBCagAwIBAgITHwAAAAjpcIxDnZn4SQAAAAAACDANBgkqhkiG9w0BAQsFADBFMRIwEAYKCZImiZPyLGQBGRYCY3MxFzAVBgoJkiaJk/IsZAEZFgdobm9wZGV2MRYwFAYDVQQDEw1obm9wZGV2LURDLUNBMB4XDTI0MDgxMzAzMTgyNFoXDTI2MDgxMzAzMjgyNFowHTEbMBkGA1UEAxMSU0FNTC5WQU1BQ0hJTkEuQ09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyLrh6AZELpktPDfUgrTprXRdVKqhQPYwMnLrMAb8AASOWZ49dt775n+YsItMr7EI31xyMcvuV+dRXKTOxoFL/0zDezKchs4WJeJa9Zguxnm6kqCaR46S++CgiNu3rMdQV9ieN4ZeAabyTMGPqny2LWJvJaUe8OWH0M5sTQq/gQ8fRgVpLgrT0CAORPsnBRsewrxdhZ0S5DJasyH+SblKtE+WG+fY3pgTDqW6cuOmSaYqTzGUV8TIpPCc2Exc6WSptWyR0t0f1bxSUBZ3gifZItsyG4DkUcFe9h3K4/+2owUY+zwYZzIKhBagKIdFXT2zi7UTfr349cfGljtEEC4wOQIDAQABo4ICTTCCAkkwPAYJKwYBBAGCNxUHBC8wLQYlKwYBBAGCNxUIj8hIgci0MIX9myuExadPgvO4DYE6raZphdjLcwIBZAIBAjATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBaAwGwYJKwYBBAGCNxUKBA4wDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQU5fy58AXegKd/pN3phOG1jcrMddwwHwYDVR0jBBgwFoAU4ewz554Mamyuv97Iwda7VCEEChUwgcUGA1UdHwSBvTCBujCBt6CBtKCBsYaBrmxkYXA6Ly8vQ049aG5vcGRldi1EQy1DQSxDTj1EQyxDTj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1obm9wZGV2LERDPWNzP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludDCBvgYIKwYBBQUHAQEEgbEwga4wgasGCCsGAQUFBzAChoGebGRhcDovLy9DTj1obm9wZGV2LURDLUNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWhub3BkZXYsREM9Y3M/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNzPWNlcnRpZmljYXRpb25BdXRob3JpdHkwDQYJKoZIhvcNAQELBQADggEBADrk+SNI8V+dlsiJgm/WbxlINu0JdScEzwk2n/osiXMep9UZXx8A2MsIApd8axbrgIoMljudaNmrKpH6XY8/JfXcRZsgrGETDBVIUjLLGjV6FcnUa0dpt2RFpx5kYJwQqnFKfXinAfCX1N3+xCavJoKM7ADjHf1Zu6XG++BdCwpQYjLLUjH7s4iym2FflRy9PkSE8rFx/NvKTCvK+3fKn346GZpQoveQadV8GJKYcyih4taYVdehHHzD2TCzqdK7DlrheyMeem+yoWQ49awstnY1FQDgWEm4g0rmgUgU6k3ulk5lGe3uZyctU4NeqgMpM/EWcmDOz5/f1V6s0IWynCI=</X509Certificate></X509Data></KeyInfo></Signature></root>
public static void RunCheck(string[] args)
        {
            bool result = false;
            // 加载XML文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.PreserveWhitespace = true;
            //xmlDoc.Load(@"C:\Users\OpenSource\Desktop\Test.xml");
            xmlDoc.LoadXml("<root><creditcard><number>19834209</number><expiry>02/02/2002</expiry></creditcard></root>");
            // 从证书存储中获取证书
            X509Certificate2 cert = GetCertificateFromStore("SAML.VAMACHINA.COM");
            // 签名XML文档
            SignXmlDocumentWithCertificate(xmlDoc, cert);
            
            // 输出签名后的XML文档
            Console.WriteLine("签名后的XML:");
            Console.WriteLine(xmlDoc.OuterXml);
           
            result = VerifyXmlDocumentSignature(xmlDoc, cert);
            Console.WriteLine("签名验证结果: " + result);
        }
        public static X509Certificate2 GetCertificateFromStore(string certName)
        {
            // 打开当前用户的证书存储
            X509Store store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            // 查找证书
            X509Certificate2Collection certCollection = store.Certificates.Find(X509FindType.FindBySubjectName, certName, false);
            store.Close();
            if (certCollection.Count > 0)
            {
                return certCollection[0];
            }
            else
            {
                throw new CryptographicException("证书未找到.");
            }
        }
        public static void SignXmlDocumentWithCertificate(XmlDocument xmlDoc, X509Certificate2 cert)
        {
            
            // 创建SignedXml对象
            SignedXml signedXml = new SignedXml(xmlDoc);
            signedXml.SigningKey = cert.PrivateKey;
            // 创建Reference对象
            Reference reference = new Reference();
            XmlDsigC14NTransform canonicalization = new XmlDsigC14NTransform();
            reference.Uri = "";
            reference.AddTransform(canonicalization);
            // 添加Reference对象到SignedXml对象
            signedXml.AddReference(reference);
            // 添加KeyInfo
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.AddClause(new KeyInfoX509Data(cert));
            signedXml.KeyInfo = keyInfo;
            // 计算签名
            signedXml.ComputeSignature();
            bool checkedResult = signedXml.CheckSignature(cert, true);
            // 获取签名XML并添加到原始文档
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            checkedResult = signedXml.CheckSignature(cert, true);
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        }
        public static bool VerifyXmlDocumentSignature(XmlDocument xmlDoc, X509Certificate2 cert)
        {
            // 创建一个新的SignedXml对象
            SignedXml signedXml = new SignedXml(xmlDoc);
            // 查找签名节点
            XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
            if (nodeList.Count <= 0)
            {
                throw new CryptographicException("签名未找到.");
            }
            // 加载签名节点
            signedXml.LoadXml((XmlElement)nodeList[0]);
            // 检查签名
            return signedXml.CheckSignature(cert, true);
        }
    }
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,822 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,883 questions
Visual Studio Debugging
Visual Studio Debugging
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Debugging: The act or process of detecting, locating, and correcting logical or syntactical errors in a program or malfunctions in hardware. In hardware contexts, the term troubleshoot is the term more frequently used, especially if the problem is major.
996 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jiale Xue - MSFT 44,841 Reputation points Microsoft Vendor
    2024-08-13T07:11:47.2966667+00:00

    Hi @谭振华 , Welcome to Microsoft Q&A,

    The canonicalization (C14N) process may differ depending on how you sign the document and how you certify it.

    You are using xmlDoc.PreserveWhitespace = true;, which preserves whitespace in the XML document. Make sure the inputs to the signing and verification processes are exactly the same, including any whitespace.

    You set reference.Uri = ""; in the SignXmlDocumentWithCertificate method. This indicates that the entire document is being signed, but it is critical that the structure of the document remains the same between signing and verification. Any changes, even minor ones, can render the signature invalid.

    public static bool VerifyXmlDocumentSignature(XmlDocument xmlDoc, X509Certificate2 cert)
    {
        // Create a new SignedXml object and pass it the XmlDocument
        SignedXml signedXml = new SignedXml(xmlDoc);
        
        // Find the "Signature" node and load it
        XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
        if (nodeList.Count <= 0)
        {
            throw new CryptographicException("Signature not found.");
        }
        
        signedXml.LoadXml((XmlElement)nodeList[0]);
        
        // Verify the signature
        bool result = signedXml.CheckSignature(cert, true);
        
        // Logging for debugging purposes
        if (!result)
        {
            Console.WriteLine("Signature verification failed.");
        }
        
        return result;
    }
    
    

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.