I have advanced something that may help you even though it is not valid:
public string FirmarXadesEpes(string path)
{
error = "true";
try
{
/* X509Certificate2Collection selectedCertificates = new X509Certificate2Collection();
selectedCertificates = ElejirCertificado();
X509Certificate2 certificado = selectedCertificates[0]; */
X509Certificate2 certificado = new X509Certificate2();
certificado = ElegirCertificado();
XmlDocument xmlDoc = new XmlDocument();
/* CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); */
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(path);
error =FirmaXadesEPES(xmlDoc, certificado,path);
}
catch (Exception ex) { error = ex.ToString(); }
return error;
}
private string FirmaXadesEPES(XmlDocument xmlDoc, X509Certificate2 certificate,string path)
{
idFirma = IdSignature();
SignedXml signedXml = new SignedXml(xmlDoc);
string URI = "http://uri.etsi.org/01903/v1.3.2#";
string uri = "http://www.w3.org/2000/09/xmldsig#";
try
{
signedXml.Signature.Id = "Id-" + idFirma;
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
signedXml.SigningKey = certificate.PrivateKey;
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot);
keyInfo.AddClause(keyInfoX509Data);
signedXml.KeyInfo = keyInfo;
//Reference 1
Reference reference = new Reference();
reference.Id = "r-id-" + idFirma;
reference.Type = "";
reference.Uri = "";
XmlDsigXPathTransform XPathTransform = CreateXPathTransform("not(ancestor-or-self::Signature)", xmlDoc);
reference.AddTransform(XPathTransform);
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
//Reference 2
Reference reference2 = new Reference();
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 qualifyingPropertiesRoot = xmlDoc.CreateElement("xades", "QualifyingProperties", URI);
qualifyingPropertiesRoot.SetAttribute("Target", "#SignatureId", URI);
XmlElement SignedSignatureProperties = xmlDoc.CreateElement("xades", "SignedSignatureProperties", URI);
XmlElement signaturePropertiesRoot = xmlDoc.CreateElement("xades", "SignedProperties", URI);
signaturePropertiesRoot.SetAttribute("Id", "SignedPropertiesId", URI);
XmlElement timestamp = xmlDoc.CreateElement("xades", "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("xades", "SigningCertificate", URI);
XmlElement Cert = xmlDoc.CreateElement("xades", "Cert", URI);
XmlElement CertDigest = xmlDoc.CreateElement("xades", "CertDigest", URI);
SHA1 cryptoServiceProvider = new SHA1CryptoServiceProvider();
byte[] sha1 = cryptoServiceProvider.ComputeHash(certificate.RawData);
XmlElement DigestMethod = xmlDoc.CreateElement("xades", "DigestMethod", URI);
DigestMethod.SetAttribute("Algorithm", SignedXml.XmlDsigSHA1Url);
XmlElement DigestValue = xmlDoc.CreateElement("xades", "DigestValue", URI);
DigestValue.InnerText = Convert.ToBase64String(sha1);
CertDigest.AppendChild(DigestMethod);
CertDigest.AppendChild(DigestValue);
Cert.AppendChild(CertDigest);
XmlElement IssuerSerial = xmlDoc.CreateElement("xades", "IssuerSerial", URI);
XmlElement X509IssuerName = xmlDoc.CreateElement("xades", "X509IssuerName", "http://www.w3.org/2000/09/xmldsig#");
X509IssuerName.InnerText = certificate.IssuerName.Name;
XmlElement X509SerialNumber = xmlDoc.CreateElement("xades", "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("xades", "SignaturePolicyIdentifier", URI);
SignedSignatureProperties.AppendChild(SignaturePolicyIdentifier);
XmlElement SignaturePolicyId = xmlDoc.CreateElement("xades", "SignaturePolicyId", URI);
SignaturePolicyIdentifier.AppendChild(SignaturePolicyId);
XmlElement SigPolicyId = xmlDoc.CreateElement("xades", "SigPolicyId", URI);
SignaturePolicyId.AppendChild(SigPolicyId);
XmlElement Identifier = xmlDoc.CreateElement("xades", "Identifier", URI);
Identifier.InnerText = "https://tribunet.hacienda.go.cr/docs/esquemas/2016/v4.2/ResolucionComprobantesElectronicosDGT-R-48-2016_4.2.pdf";
SigPolicyId.AppendChild(Identifier);
XmlElement SigPolicyHash = xmlDoc.CreateElement("", "SigPolicyHash", URI);
SignaturePolicyId.AppendChild(SigPolicyHash);
DigestMethod = xmlDoc.CreateElement("xades", "DigestMethod", URI);
DigestMethod.SetAttribute("Algorithm", "http://www.w3.org/2001/04/xmlenc#sha256");
DigestValue = xmlDoc.CreateElement("xades", "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);*/
DigestValue.InnerText = "eUGBLxo7SaqxaR+CGU5DCjUc514GOiOU9S0Smy5W7HE=";
//"V8lVVNGDCPen6VELRD1Ja8HARFk="; "NmI5Njk1ZThkNzI0MmIzMGJmZDAyNDc4YjUwNzkzODM2NTBiOWUxNTBkMmI2YjgzYzZjM2I5NTZlNDQ4OWQzMQ=="; "LpeabLa3KYF9gfEAYYMFtkhtoR8=";"5EsGNDZGSknyxAIJSI+u0dERTL0=";
SigPolicyHash.AppendChild(DigestMethod);
SigPolicyHash.AppendChild(DigestValue);
XmlElement SignedDataObjectProperties = xmlDoc.CreateElement("xades", "SignedDataObjectProperties", URI);
XmlElement DataObjectFormat = xmlDoc.CreateElement("xades", "DataObjectFormat", URI);
DataObjectFormat.SetAttribute("ObjectReference", "#r-id-1");
signaturePropertiesRoot.AppendChild(SignedDataObjectProperties);
SignedDataObjectProperties.AppendChild(DataObjectFormat);
XmlElement MimeType = xmlDoc.CreateElement("xades", "MimeType", URI);
MimeType.InnerText = "application/octet-stream";
DataObjectFormat.AppendChild(MimeType);
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DataObject dataObject = new DataObject
{
Data = qualifyingPropertiesRoot.SelectNodes("."),
};
signedXml.AddObject(dataObject);
// /////////////////////////////////////////////////////////////
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
bool checkSign = signedXml.CheckSignature();
} catch (Exception ex) { error = ex.ToString(); }
xmlDoc.Save(path);
//return xmlDoc.OuterXml;
return error;
}
private static XmlDsigXPathTransform CreateXPathTransform(string XPathString, XmlDocument doc)
{
XmlElement xPathElem = doc.CreateElement("XPath");
xPathElem.InnerText = XPathString;
XmlDsigXPathTransform xForm = new XmlDsigXPathTransform();
xForm.LoadInnerXml(xPathElem.SelectNodes("."));
return xForm;
}