I develop an application that signs an XML document ... even there perfect ...
But I must change the order in which these elements appear
-<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id-e34ffbff277e8d1432e864436aa118824">
It should look like this:
-<Signature Id="id-e34ffbff277e8d1432e864436aa118824" xmlns="http://www.w3.org/2000/09/xmldsig#" >
My code
private XmlDocument FirmaXadesEPES(XmlDocument xmlDoc, X509Certificate2 certificate)
{
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.Signature.Id = "id-e34ffbff277e8d1432e864436aa118824";
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
string URI = "http://uri.etsi.org/01903/v1.3.2#";
XmlElement qualifyingPropertiesRoot = xmlDoc.CreateElement("", "QualifyingProperties", URI);
qualifyingPropertiesRoot.SetAttribute("Target", "#SignatureId", URI);
XmlElement SignedSignatureProperties = xmlDoc.CreateElement("", "SignedSignatureProperties", URI);
XmlElement signaturePropertiesRoot = xmlDoc.CreateElement("", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", "SignedPropertiesId", URI);
XmlElement timestamp = xmlDoc.CreateElement("", "SigningTime", URI);
timestamp.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); //2011-09-05T09:11:24.268Z
SignedSignatureProperties.AppendChild(timestamp);
XmlElement SigningCertificate = xmlDoc.CreateElement("", "SigningCertificate", URI);
XmlElement Cert = xmlDoc.CreateElement("", "Cert", URI);
XmlElement CertDigest = xmlDoc.CreateElement("", "CertDigest", URI);
SHA1 cryptoServiceProvider = new SHA1CryptoServiceProvider();
byte[] sha1 = cryptoServiceProvider.ComputeHash(certificate.RawData);
XmlElement DigestMethod = xmlDoc.CreateElement("", "DigestMethod", URI);
DigestMethod.SetAttribute("Algorithm", SignedXml.XmlDsigSHA1Url);
XmlElement DigestValue = xmlDoc.CreateElement("", "DigestValue", URI);
DigestValue.InnerText = Convert.ToBase64String(sha1);
CertDigest.AppendChild(DigestMethod);
CertDigest.AppendChild(DigestValue);
Cert.AppendChild(CertDigest);
XmlElement IssuerSerial = xmlDoc.CreateElement("", "IssuerSerial", URI);
XmlElement X509IssuerName = xmlDoc.CreateElement("", "X509IssuerName", "http://www.w3.org/2000/09/xmldsig#");
X509IssuerName.InnerText = certificate.IssuerName.Name;
XmlElement X509SerialNumber = xmlDoc.CreateElement("", "X509SerialNumber", "http://www.w3.org/2000/09/xmldsig#");
X509SerialNumber.InnerText = certificate.SerialNumber;
IssuerSerial.AppendChild(X509IssuerName);
IssuerSerial.AppendChild(X509SerialNumber);
Cert.AppendChild(IssuerSerial);
SigningCertificate.AppendChild(Cert);
SignedSignatureProperties.AppendChild(SigningCertificate);
signaturePropertiesRoot.AppendChild(SignedSignatureProperties);
qualifyingPropertiesRoot.AppendChild(signaturePropertiesRoot);
// /////////////////////////////////
XmlElement SignaturePolicyIdentifier = xmlDoc.CreateElement("", "SignaturePolicyIdentifier", URI);
SignedSignatureProperties.AppendChild(SignaturePolicyIdentifier);
XmlElement SignaturePolicyId = xmlDoc.CreateElement("", "SignaturePolicyId", URI);
SignaturePolicyIdentifier.AppendChild(SignaturePolicyId);
XmlElement SigPolicyId = xmlDoc.CreateElement("", "SigPolicyId", URI);
SignaturePolicyId.AppendChild(SigPolicyId);
XmlElement Identifier = xmlDoc.CreateElement("", "Identifier", URI);
Identifier.InnerText = "https://tribunet.hacienda.go.cr/docs/esquemas/2016/v4.1/Resolucion_Comprobantes_Electronicos_DGT-R-48-2016.pdf";
SigPolicyId.AppendChild(Identifier);
XmlElement SigPolicyHash = xmlDoc.CreateElement("", "SigPolicyHash", URI);
SignaturePolicyId.AppendChild(SigPolicyHash);
DigestMethod = xmlDoc.CreateElement("", "DigestMethod", URI);
DigestMethod.SetAttribute("Algorithm", "http://www.w3.org/2001/04/xmlenc#sha256");
DigestValue = xmlDoc.CreateElement("", "DigestValue", URI);
byte[] shaCertificate = { 0x06, 0xb3, 0x90, 0xb6, 0x45, 0xbb, 0x68, 0x3a, 0xde, 0x72, 0x8e, 0xb8, 0xf9, 0x79, 0x27, 0xd9, 0x18, 0x01, 0x67, 0xdb };
SHA256 sigPolicyHash = SHA256Managed.Create();
byte[] sigPolicyHashValue = sigPolicyHash.ComputeHash(shaCertificate);
DigestValue.InnerText = Convert.ToBase64String(sigPolicyHashValue);
SigPolicyHash.AppendChild(DigestMethod);
SigPolicyHash.AppendChild(DigestValue);
XmlElement SignedDataObjectProperties = xmlDoc.CreateElement("", "SignedDataObjectProperties", URI);
XmlElement DataObjectFormat = xmlDoc.CreateElement("", "DataObjectFormat", URI);
DataObjectFormat.SetAttribute("ObjectReference", "#r-id-1");
signaturePropertiesRoot.AppendChild(SignedDataObjectProperties);
SignedDataObjectProperties.AppendChild(DataObjectFormat);
XmlElement MimeType = xmlDoc.CreateElement("", "MimeType", URI);
MimeType.InnerText = "application/octet-stream";
DataObjectFormat.AppendChild(MimeType);
// /////////////////////////////////////////////////////////////
DataObject dataObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
};
signedXml.AddObject(dataObject);
signedXml.SigningKey = certificate.PrivateKey;
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot);
keyInfo.AddClause(keyInfoX509Data);
signedXml.KeyInfo = keyInfo;
//Reference 1
Reference reference2 = new Reference();
reference2.Id = "r-id-1";
//reference2.Type = "http://uri.etsi.org/01903#SignedProperties";
reference2.Type = "";
reference2.Uri = "";
XmlDsigXPathTransform XPathTransform = CreateXPathTransform("//. | //@* | //namespace::*", xmlDoc);
reference2.AddTransform(XPathTransform);
reference2.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
reference2.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference2);
//Reference 2
reference2 = new Reference();
// reference2.Id = "R2";
reference2.Type = "http://uri.etsi.org/01903#SignedProperties";
reference2.Uri = "";
reference2.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
reference2.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference2);
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
bool checkSign = signedXml.CheckSignature();
//return xmlDoc.OuterXml;
return xmlDoc;
}