我正在用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上签名的位置吗?
答案 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");