在另一个位置签名xml标签

时间:2015-03-26 19:28:21

标签: c# xml x509certificate2 xml-signature xml-dsig

我正在用c#签署一份文件 使用此代码

public class program
    {
        static void Main(String[] arg)
        {
            string xmlString = File.ReadAllText(@"D:\E-Billing\Demo.xml");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlString);
            //doc.Load(@"D:\E-Billing\Demo.xml");

            string pfxStr = @"D:\E-Billing\jojolete.pfx";
            X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(pfxStr),"cabanillas");
            SignedXMLWithCertificate(doc, cert);

            Console.WriteLine(doc.OuterXml);
            doc.Save(@"D:\E-Billing\Demo2.xml");

        }

        public static void SignedXMLWithCertificate(XmlDocument doc, X509Certificate2 cert)
        {
            SignedXml signedXML = new SignedXml(doc);
            signedXML.SigningKey = cert.PrivateKey;
            Reference reference = new Reference();
            reference.Uri = "";
            reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            signedXML.AddReference(reference);

            KeyInfo keyinfo = new KeyInfo();
            keyinfo.AddClause(new KeyInfoX509Data(cert));
            signedXML.KeyInfo = keyinfo;
            signedXML.ComputeSignature();
            XmlElement xmlsig = signedXML.GetXml();

            //doc.DocumentElement.AppendChild(doc.ImportNode(xmlsig, true));
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("ext", "");
        doc.SelectSingleNode("/Invoice/ext:ExtensionContent", nsmgr).AppendChild(doc.ImportNode(xmlsig, true));

        }

我要签名的Xml文档具有以下标记,用于插入签名

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<Invoice>
 <ext:UBLExtensions>
 <ext:UBLExtension>
 <ext:ExtensionContent>
 <sac:AdditionalInformation>
 <sac:AdditionalMonetaryTotal>
 <cbc:ID>1001</cbc:ID>
 <cbc:PayableAmount currencyID="PEN">348199.15</cbc:PayableAmount>
 </sac:AdditionalMonetaryTotal>
 <sac:AdditionalMonetaryTotal>
 <cbc:ID>1003</cbc:ID>
 <cbc:PayableAmount currencyID="PEN">12350.00</cbc:PayableAmount>
 </sac:AdditionalMonetaryTotal>
 <sac:AdditionalMonetaryTotal>
 <cbc:ID>1004</cbc:ID>
 <cbc:PayableAmount currencyID="PEN">30.00</cbc:PayableAmount>
 </sac:AdditionalMonetaryTotal>
 <sac:AdditionalMonetaryTotal>
 <cbc:ID>2005</cbc:ID>
 <cbc:PayableAmount currencyID="PEN">59230.51</cbc:PayableAmount>
 </sac:AdditionalMonetaryTotal>
 <sac:AdditionalProperty>
 <cbc:ID>1000</cbc:ID>
 <cbc:Value>CUATROCIENTOS VEINTITRES MIL DOSCIENTOS VEINTICINCO Y
00/100</cbc:Value>
 </sac:AdditionalProperty>
 </sac:AdditionalInformation>
 </ext:ExtensionContent>
 </ext:UBLExtension>
 <ext:UBLExtension>
    <ext:ExtensionContent>
        <ds:Signature Id="SignatureSP">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                <ds:Reference URI="">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envelopedsignature"/>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>ryg5Vl+...Qjk=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>SOiGQp....ffb0=</ds:SignatureValue>
            <ds:KeyInfo>
                <ds:X509Data>
                    <ds:X509SubjectName>1.2IMA,ST=LIMA,C=PE</ds:X509SubjectName>
                    <ds:X509Certificate>MIIESTCCAzGgAwIBAgIKWOC++GxDtaK/5EiVKSqzJ6geIfz</ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </ds:Signature>
    </ext:ExtensionContent>
 </ext:UBLExtension>
</ext:UBLExtensions>
 more tags
</Invoice>

但标签签名出现在最后

<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>GF0......OR/nXwTxw=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>JQLyp...wEN6Th</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>o6pQR6K.......XJODMUu</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
</Invoice>

我可以移动或分配他们将在xml上签名的位置吗?

1 个答案:

答案 0 :(得分:0)

您可以更改代码的最后一行

doc.DocumentElement.AppendChild(doc.ImportNode(xmlsig, true));

doc.SelectSingleNode("/Invoice/ext:ExtensionContent", nsmgr).AppendChild(doc.ImportNode(xmlsig, true));

文档节点是根节点,因此它将附加在那里。 SelectSingleNode()使用XPath选择要导入的其他节点。请注意,您需要ext前缀的命名空间管理器。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ext","uri-of-ext");