1

I am trying to write a function to sign an XML file using SHA256. The resulting file has the correct digest value. Everything else seems to be correct as well, except for the Signature Value. My function is below. I believe I'm currently signing the entire file. I only need to sign a portion of the file (everything inside of ). How do I specify only a portion of the XML to sign?

public static void SignXmlFile(string FileName, string SignedFileName)
    {
        //Load the *.p12 file into the certificate
        X509Certificate2 cert = new X509Certificate2(@"C:\...\filename.p12", "password");

        //Create a new XML Document
        XmlDocument doc = new XmlDocument();

        //Format the document to ignore white spaces
        doc.PreserveWhitespace = false;

        //Load the passed XML file using the file name
        doc.Load(new XmlTextReader(FileName));

        //adding algorithm for 256.  Will change the actual values below.
        CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

        //Create a signed XML object
        SignedXml signedXml = new SignedXml(doc);

        //Add the key to the Signed XML document
        signedXml.SigningKey = cert.PrivateKey;

        //Create a reference to be signed
        Reference reference = new Reference();
        reference.Uri = "";

        //Add an enveloped transformation to the reference
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        //Set the Signature, Canonicalization, and Digets Methods
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
        signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

        //Add the new reference to the signedXml
        signedXml.SignedInfo.AddReference(reference);

        //Create a new KeyInfo object
        KeyInfo keyInfo = new KeyInfo();

        //Add subject name and key to the keyInfo to sign
        KeyInfoX509Data keyData = new KeyInfoX509Data(cert);
        keyData.AddSubjectName(cert.SubjectName.Name);
        keyInfo.AddClause(keyData);

        //Add the KeyInfo object to the signed XML object
        signedXml.KeyInfo = keyInfo;

        //Compute the signature
        signedXml.ComputeSignature();

        //Get the XML representation of the signature and save it to an XmlElement object
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        //Append the element to the XML document
        doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

        if (doc.FirstChild is XmlDeclaration)
        {
            doc.RemoveChild(doc.FirstChild);
        }

        //Save the signed XML document to the specified file
        using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)))
        {
            doc.WriteTo(xmltw);
            xmltw.Close();
        }
    }
4

0 回答 0