ESocial - Error signing XML

1

Good afternoon.

I'm trying to sign the XML, however I'm having the error below:

  

Error generating System.Security.Cryptography.CryptographicException: Malformed Reference Element.

Searching, I saw that the problem is in the referring line.uri="#" + id;

The id variable is set to the value "ID1122632750001052017122616320300001"

Has anyone experienced anything like this?

Follow the code:

public static void GeraXMLAssinado(String caminho){

    XmlDocument doc = new XmlDocument();
    doc.Load(caminho);

    XmlNodeList ListInfNFe = doc.GetElementsByTagName("evento");
    foreach (XmlElement infNFe in ListInfNFe)
    {
        string id = infNFe.Attributes.GetNamedItem("Id").Value;
        SignedXml xml = new SignedXml(infNFe);

        xml.SigningKey = AssinaXMl().PrivateKey;

        // Transformações p/ DigestValue da Nota
        Reference reference = new Reference();
        reference.Uri = "#" + id;
        reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
        reference.AddTransform(new XmlDsigC14NTransform());
        xml.AddReference(reference);

        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new KeyInfoX509Data(AssinaXMl()));
        xml.KeyInfo = keyInfo;

        xml.ComputeSignature();

        XmlElement xmlSignature = doc.CreateElement("Signature", "http://www.w3.org/2000/09/xmldsig#");
        XmlElement xmlSignedInfo = xml.SignedInfo.GetXml();
        XmlElement xmlKeyInfo = xml.KeyInfo.GetXml();


        XmlElement xmlSignatureValue = doc.CreateElement("SignatureValue", xmlSignature.NamespaceURI);
        string signBase64 = Convert.ToBase64String(xml.Signature.SignatureValue);
        XmlText text = doc.CreateTextNode(signBase64);
        xmlSignatureValue.AppendChild(text);
        xmlSignature.AppendChild(xmlSignatureValue);


        xmlSignature.AppendChild(doc.ImportNode(xmlSignedInfo, true));
        xmlSignature.AppendChild(doc.ImportNode(xmlKeyInfo, true));
        doc.AppendChild(xmlSignature);
        doc.Save(caminho);
    }
}
    
asked by anonymous 26.12.2017 / 19:33

1 answer

2

Rodrigo, in the eSocial the URI element of the signature should be empty, you should not enter the event id.

Also, avoid creating signature tags , instead, try doing this:

signedXml.ComputeSignature();

XmlElement xmlDigitalSignature = signedXml.GetXml();

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

I made a page a while ago with some tips on how to sign an eSocial event XML, see if it helps with something:

  

link

But, briefly, the code I'm using is as follows:

  //
  // SignedXml.CheckSignature Method (X509Certificate2, Boolean) -> Examples [SHA1]
  // https://msdn.microsoft.com/en-us/library/ms148731(v=vs.110).aspx
  //
  // Using SHA256 with the SignedXml Class
  // https://blogs.msdn.microsoft.com/winsdk/2015/11/14/using-sha256-with-the-signedxml-class/
  //
  private static void SignXmlDoc(XmlDocument xmlDoc, X509Certificate2 certificate)
  {
     //
     // https://docs.microsoft.com/en-us/dotnet/framework/whats-new/#Crypto462
     //
     // SignedXml support for SHA-2 hashing The .NET Framework 4.6.2 adds support
     // to the SignedXml class for RSA-SHA256, RSA-SHA384, and RSA-SHA512 PKCS#1
     // signature methods, and SHA256, SHA384, and SHA512 reference digest algorithms.
     //
     // Any programs that have registered a custom SignatureDescription handler into CryptoConfig
     // to add support for these algorithms will continue to function as they did in the past, but
     // since there are now platform defaults, the CryptoConfig registration is no longer necessary.
     //
     //// First of all, we need to register a SignatureDescription class that defines the DigestAlgorithm as SHA256.
     //// You have to reference the System.Deployment assembly in your project.
     //CryptoConfig.AddAlgorithm(
     //   typeof(System.Deployment.Internal.CodeSigning.RSAPKCS1SHA256SignatureDescription),
     //   "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
     // RSAPKCS1SHA256SignatureDescription -> Disponível desde .NET Framework 4.5

     SignedXml signedXml = new SignedXml(xmlDoc);

     // Add the key to the SignedXml document. 
     signedXml.SigningKey = certificate.GetRSAPrivateKey();   // Disponível desde .NET Framework 4.6
     //signedXml.SigningKey = GetRSAPrivateKey(certificate);

     //
     // https://docs.microsoft.com/en-us/dotnet/framework/whats-new/#Crypto462
     //
     // SignedXml support for SHA-2 hashing The .NET Framework 4.6.2 adds support
     // to the SignedXml class for RSA-SHA256, RSA-SHA384, and RSA-SHA512 PKCS#1
     // signature methods, and SHA256, SHA384, and SHA512 reference digest algorithms.
     signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA256Url; //"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"

     // Create a reference to be signed. Pass "" to specify that
     // all of the current XML document should be signed.
     Reference reference = new Reference(string.Empty);

     reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
     reference.AddTransform(new XmlDsigC14NTransform());
     reference.DigestMethod = SignedXml.XmlDsigSHA256Url; //""http://www.w3.org/2001/04/xmlenc#sha256"

     // Add the reference to the SignedXml object.
     signedXml.AddReference(reference);

     signedXml.KeyInfo = new KeyInfo();
     // Load the certificate into a KeyInfoX509Data object
     // and add it to the KeyInfo object.
     signedXml.KeyInfo.AddClause(new KeyInfoX509Data(certificate));

     // 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));

     if (xmlDoc.FirstChild is XmlDeclaration)
        xmlDoc.RemoveChild(xmlDoc.FirstChild);
  }
    
20.02.2018 / 04:42