How to sign XML with XAdES-EPES

2

I need to sign an XML with the following specifications:

  • The version of the ETSI TS 101 903 is adjusted to v1.3.2 or higher.
  • The URL to be used for the XAdES-EPES policy is added.
  • It is clarified that the packaging of the XAdES will be ENVELOPED.
  • It is indicated that the encryption algorithms of the certificates must be RSA 2048 or RSA 4096.
  • It is indicated that the digest algorithms of the signature must be SHA-256 and SHA-512.
  • Text about Law 8454 is added.
  • Example of a ds: Signature tag is added.
  • The value of the policy ID to version v4.1 is modified
  • Change the signature example so that it has the Policy information in version v4.1
  • If someone can help me, I would really appreciate it.

    Try to sign it in the usual way as follows, but in that way it does not meet the requested requirements:

    // Create a new CspParameters object to specify a key container.
                    CspParameters cspParams = new CspParameters();
                    cspParams.KeyContainerName = "010945029010.p12";
    
                    //XML_DSIG_RSA_KEY
    
                    // Create a new RSA signing key and save it in the container. 
                    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
                    // Create a new XML document.
                    XmlDocument xmlDoc = new XmlDocument();
    
                    // Load an XML file into the XmlDocument object.
                    xmlDoc.PreserveWhitespace = true;
                    xmlDoc.Load(strRuta);
    
                    // Sign the XML document. 
                    SignXml(xmlDoc, rsaKey);
    
                    // Save the document.
                    xmlDoc.Save(strRuta);
    
    // Check arguments.
            if (xmlDoc == null)
                throw new ArgumentException("xmlDoc");
            if (Key == null)
                throw new ArgumentException("Key");
    
            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(xmlDoc);
    
            // Add the key to the SignedXml document.
            signedXml.SigningKey = Key;
    
            // 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);
    
            // Compute the signature.
            signedXml.ComputeSignature();
    
            // Get the XML representation of the signature and save
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();
    
            // Append the element to the XML document.
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
        
    asked by Arnold Ulate Segura 15.11.2017 в 21:35
    source

    2 answers

    0

    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;
            }
    
        
    answered by 01.02.2018 в 20:04
    0

    In Spain we have a very powerful client which we can specify by parameters as we want to sign as well as the policies or types of signatures perfectly adjusting to the requirements you need, it is very robust. It is an application that is installed on the client's side and performs electronic signatures in the way you have specified it.

    Application of signatures: Self-signature

    You can validate them at: eValide

    The way to invoke the application is through JavaScript code: Here you can find information about how to invoke Autofirma as well as the JavaScritp code necessary for its operation.

    Any question you can put a comment.

    Greetings.

        
    answered by 05.07.2018 в 09:08