Verify Digitaly Means XML Is Always False

I create a key value using the following script

    sn.exe -k KeyFile.snk
sn.exe -m y
sn.exe -i KeyFile.snk test

then i use it to validate and sign my xml with the following snipet code

    private void SignXml(XmlDocument xmlDoc )
    {

        CspParameters parms = new CspParameters(1);         // PROV_RSA_FULL
        parms.Flags = CspProviderFlags.UseMachineKeyStore;  // Use Machine store
        parms.KeyContainerName = "test";                // "CodeProject" container
        parms.KeyNumber = 2;                                // AT_SIGNATURE
        RSACryptoServiceProvider csp = new RSACryptoServiceProvider(parms);

        // Creating the XML signing object.
        SignedXml sxml = new SignedXml(xmlDoc);
        sxml.SigningKey = csp;

        // Set the canonicalization method for the document.
        sxml.SignedInfo.CanonicalizationMethod =
            SignedXml.XmlDsigCanonicalizationUrl; // No comments.

        // Create an empty reference (not enveloped) for the XPath
        // transformation.
        Reference r = new Reference("");

        // Create the XPath transform and add it to the reference list.
        r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false));

        // Add the reference to the SignedXml object.
        sxml.AddReference(r);

        // Compute the signature.
        sxml.ComputeSignature();

        // Get the signature XML and add it to the document element.
        XmlElement sig = sxml.GetXml();
        if (xmlDoc.DocumentElement != null) 
            xmlDoc.DocumentElement.AppendChild(sig);

    }
  public static Boolean VerifyXml(XmlDocument doc)
        {

            // Get the XML content from the embedded XML public key.
            Stream s = null;
            string xmlkey = string.Empty;
            try
            {
                s = typeof(Program).Assembly.GetManifestResourceStream(
                    "LicenceVerifier.PubKey.xml");

                // Read-in the XML content.
                StreamReader reader = new StreamReader(s);
                xmlkey = reader.ReadToEnd();
                reader.Close();
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error: could not import public key: {0}",
                    e.Message);
                return false;
            }

            // Create an RSA crypto service provider from the embedded
            // XML document resource (the public key).
            RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
            csp.FromXmlString(xmlkey);

            // Create the signed XML object.
            SignedXml sxml = new SignedXml(doc);

            try
            {
                // Get the XML Signature node and load it into the signed XML object.
                XmlNode dsig = doc.GetElementsByTagName("Signature",
                    SignedXml.XmlDsigNamespaceUrl)[0];
                sxml.LoadXml((XmlElement)dsig);
            }
            catch
            {
                Console.Error.WriteLine("Error: no signature found.");
                return false;
            }

            // Verify the signature.
            if (sxml.CheckSignature(csp))
                return true;
            else
                return false;

the problem that checks always returns false, even if I use the public key of the key, any idea how to solve this, part of the signature looks like this:

  <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/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>XT/TOXNZ6SEe6V3c6Ulxa/rOzLE=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>t1C/ycVh/8nV1uvc9WKbOTawKQjg3luUi7717AQDHc4N+g7DDHYHAb2zvoSEUTCHIkY9UFenoZqjbLwL9/ejyef/kQe8V/jrj0GZ60BNp8ee0nXSfr91wEdhOo9qqSo/iPbnP8By9tJnbOcJG7EFWjorgMITfHGct4QXfMZFoh4=</SignatureValue>
  </Signature>

I use them as

SignXml(xmlDoc); // where xmlDoc is the xmldocument i create to be signed 
///////////////// TO Verify //////////////
            try
            {
                // Create a new CspParameters object to specify
                // a key container.

                Console.WriteLine("Type path");
                var path = Console.ReadLine();

                // Create a new XML document.
                XmlDocument xmlDoc = new XmlDocument();

                // Load an XML file into the XmlDocument object.
                xmlDoc.PreserveWhitespace = true;
                xmlDoc.Load(path);

                // Verify the signature of the signed XML.
                Console.WriteLine("Verifying signature...");
                bool result = VerifyXml(xmlDoc);

                // Display the results of the signature verification to 
                // the console.
                if (result)
                {
                    Console.WriteLine("The XML signature is valid.");
                }
                else
                {
                    Console.WriteLine("The XML signature is not valid.");
                }

                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
+4
source share
2 answers

On the verifier, make sure that

xmlDoc.PreserveWhitespace = false;
0
source

It seems to me that you are using the publik key incorrectly. First, check if the LicenceVerifier.PubKey.xml file is installed with the Build Action setting for the embedded resource.

Then run this code in debugging:

typeof(Program).Assembly.GetManifestResourceNames()

, GetManifestResourceStream. , :

var asm = typeof(Program).Assembly;
s = asm.GetManifestResourceStream(asm.GetName().Name + ".LicenceVerifier.PubKey.xml");

, :

var subFolder = "NAME";
var asm = typeof(Program).Assembly;
s = asm.GetManifestResourceStream(asm.GetName().Name + "." + subFolder + ".LicenceVerifier.PubKey.xml");

, , . :

private static string SignXml(XmlDocument xmlDoc)
{
   ...
   return csp.ToXmlString(false);
}

public static Boolean VerifyXml(XmlDocument doc, string xmlKey)
{
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
    csp.FromXmlString(xmlKey);
    ...
}

var xmlKey = SignXml(xml);
var res = VerifyXml(xml, xmlKey);

, LicenceVerifier.PubKey.xml xml, SignXml.

+3

Source: https://habr.com/ru/post/1616275/


All Articles