如何签名(x.509)XML元素?

时间:2015-08-31 15:26:24

标签: c# xml x509certificate

我需要使用X.509证书

签署一个XML文件

此刻我有(复制形式msdn)

    public static void SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert)
    {

        RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)uidCert.PrivateKey;


        // Check arguments. 
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (rsaKey == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = rsaKey;


        // 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);

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


        // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
        KeyInfo keyInfo = new KeyInfo();

        KeyInfoX509Data clause = new KeyInfoX509Data();
        clause.AddSubjectName(uidCert.Subject);
        clause.AddCertificate(uidCert);
        keyInfo.AddClause(clause);
        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();

        System.Console.WriteLine(signedXml.GetXml().InnerXml);

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

当我运行它时,会生成一个像

这样的文件
<root>
   <myelement>.....</myelement>
   <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
   ....
   </Signature>
   ....

但需要此文件的人告诉我这个错误,他们需要该文件已签名myelement内容

对于exmaple,他们需要像这样的结果文件

<root>
   <myelement>
      <Signature>.....
      </Signature>
   </myelement>
</root>

我是怎么做到的?

1 个答案:

答案 0 :(得分:0)

试试这个。我在SignXml()

的末尾修改了几行
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            string input =
                "<?xml version=\"1.0\"?>" +
                "<root></root>";

            doc.LoadXml(input);

            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certCollection = store.Certificates;

            SignXml(doc, certCollection[0]);
        }


        public static void SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert)
        {

            RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)uidCert.PrivateKey;


            // Check arguments. 
            if (xmlDoc == null)
                throw new ArgumentException("xmlDoc");
            if (rsaKey == null)
                throw new ArgumentException("Key");

            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(xmlDoc);

            // Add the key to the SignedXml document.
            signedXml.SigningKey = rsaKey;


            // 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);

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


            // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
            KeyInfo keyInfo = new KeyInfo();

            KeyInfoX509Data clause = new KeyInfoX509Data();
            clause.AddSubjectName(uidCert.Subject);
            clause.AddCertificate(uidCert);
            keyInfo.AddClause(clause);
            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();

            System.Console.WriteLine(signedXml.GetXml().InnerXml);

            // Append the element to the XML docu0ment.
            XmlElement root = (XmlElement)xmlDoc.GetElementsByTagName("root")[0];
            XmlElement myElement = xmlDoc.CreateElement("myelement");
            root.AppendChild(myElement);
            myElement.AppendChild(xmlDigitalSignature);
        }
    }
}
​