eSocial: Invalid Signature .NET Framework

2

Invalid Signature

Good afternoon, I have a problem transmitting information to eSocial webservices. The process I do is as follows: Event XMLs are generated on the server, returned to an application that runs on the client machine and is responsible for signing the events and performing the transmission to eSocial. The transmission of the batch is made and received successfully, but when querying the information through the query webservice (by the delivery receipt returned in the shipment) a code error 142 is returned and description Signature of the Invalid event. Suggested Actions: Check if event has changed after signing. Verify signature validity.

I'll put down the uploaded file and the method responsible for signing. (Certificate data has been omitted)

<eSocial xmlns="http://www.esocial.gov.br/schema/lote/eventos/envio/v1_1_1">
  <envioLoteEventos grupo="2">
    <ideEmpregador>
      <tpInsc>1</tpInsc>
      <nrInsc>95784204000177</nrInsc>
    </ideEmpregador>
    <ideTransmissor>
      <tpInsc>1</tpInsc>
      <nrInsc>05964161000119</nrInsc>
    </ideTransmissor>
    <eventos>
      <evento Id="ID1957842040001772018121314262900000">
        <eSocial xmlns="http://www.esocial.gov.br/schema/evt/evtToxic/v02_05_00">
          <evtToxic Id="ID1957842040001772018120609352600000">
            <ideEvento>
              <indRetif>0</indRetif>
              <tpAmb>2</tpAmb>
              <procEmi>1</procEmi>
              <verProc>01.00.00</verProc>
            </ideEvento>
            <ideEmpregador>
              <tpInsc>1</tpInsc>
              <nrInsc>95784204000177</nrInsc>
            </ideEmpregador>
            <ideVinculo>
              <cpfTrab>56641686094</cpfTrab>
              <nisTrab>12025177234</nisTrab>
              <matricula>621</matricula>
            </ideVinculo>
            <toxicologico>
              <dtExame>2018-12-06</dtExame>
              <indRecusa>S</indRecusa>
            </toxicologico>
          </evtToxic>
          <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/2001/04/xmldsig-more#rsa-sha256" />
              <Reference URI="">
                <Transforms>
                  <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                  <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <DigestValue>...</DigestValue>
              </Reference>
            </SignedInfo>
            <SignatureValue>...</SignatureValue>
            <KeyInfo>
              <X509Data>
                <X509Certificate>...</X509Certificate>
              </X509Data>
            </KeyInfo>
          </Signature>
        </eSocial>
      </evento>
    </eventos>
  </envioLoteEventos>
</eSocial>

Here is the code responsible for creating the batch and then the event signature.

var cl = new WSEsocial.Envio.ServicoEnviarLoteEventosClient();

cl.ClientCredentials.ClientCertificate.SetCertificate(cert.SubjectName.Name, System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, System.Security.Cryptography.X509Certificates.StoreName.My);

XmlElement _getXmlElement(string xml)
{
  var d = new XmlDocument();
  d.LoadXml(_serviceSign.Sign(cert, xml).OuterXml);
  return d.DocumentElement;
}

var lote = new eSocial()
{
  envioLoteEventos = new eSocialEnvioLoteEventos()
  {
    grupo = (sbyte)model.GrupoEvento,
    ideEmpregador = new TIdeEmpregador()
    {
      nrInsc = model.UnidadeInsc,
      tpInsc = (sbyte)model.TipoInsc
    },
    ideTransmissor = new TIdeTransmissor()
    {
      nrInsc = cnpj,
      tpInsc = (sbyte)1
    },
    eventos = new eSocialEnvioLoteEventosEventos()
    {
      evento = model.Eventos.Select(x => new TArquivoEsocial
      {
        Id = x.Id,
        Any = _getXmlElement(x.XmlString)
      }).ToList()
    }
  }
};

public XmlDocument Sign(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, string xmlString)
    {
      var doc = new XmlDocument();
      doc.PreserveWhitespace = false;
      doc.LoadXml(xmlString);

      Reference referenc = new Reference
      {
        Uri = string.Empty,
        DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256",
      };
      referenc.AddTransform(new XmlDsigEnvelopedSignatureTransform());
      referenc.AddTransform(new XmlDsigC14NTransform());
      referenc.DigestMethod = XmlSignatureExtensions.SHA256DIGEST;

      var kInfo = new KeyInfo();
      kInfo.AddClause(new KeyInfoX509Data(cert));


      var privKey   = (RSACryptoServiceProvider)cert.PrivateKey;
      var enhCsp    = new RSACryptoServiceProvider().CspKeyContainerInfo;

      var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privKey.CspKeyContainerInfo.KeyContainerName);
      privKey       = new RSACryptoServiceProvider(cspparams);

      var signDoc = new SignedXml(doc)
      {
        KeyInfo = kInfo,
        SigningKey = privKey
      };
      signDoc.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
      signDoc.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;
      signDoc.AddReference(referenc);


      signDoc.ComputeSignature();

      doc.DocumentElement.AppendChild(doc.ImportNode(signDoc.GetXml(), true));

      return doc;
    }

Thank you very much if someone can give me a light on. Thank you

    
asked by anonymous 20.12.2018 / 17:19

1 answer

1

I kick that the problem should be in the way you are getting the private key of the certificate, to sign the XML. Note that you are taking the ProviderType and ProviderName properties of the newly created% object, rather than the certificate's private key:

var privKey   = (RSACryptoServiceProvider)cert.PrivateKey;
var enhCsp    = new RSACryptoServiceProvider().CspKeyContainerInfo;

var cspparams = new CspParameters(enhCsp.ProviderType,
                                  enhCsp.ProviderName,
                                  privKey.CspKeyContainerInfo.KeyContainerName);
privKey       = new RSACryptoServiceProvider(cspparams);

This may not be your current problem, but may be a problem in the future, because when you instantiate a new object of class RSACryptoServiceProvider , the default key is used ( documentation ), and the default key may not be the key you want to use for the signature .

See my other answer in Stack Overflow on the subject:

  

E-Social. Invalid Event Signing - Stack Overflow in English

There is an example of a routine used to sign the XML and also some reasoning tips that may cause this invalid signature error.

See also this latest response, which is about EFD-Reinf, but is very similar to eSocial (the difference is that in EFD-Reinf the RSACryptoServiceProvider attribute must have content and eSocial must be empty) :

  

EFD-Reinf: Signature Error - An XmlDocument Context is Required for Enveloped Transforms

Another thing, the S-2221 event you are trying to send in the example, is part of the Worker Health and Safety - SST , which will only be sent from July / 2019 to the companies of Group 1 ( news ).

If you are starting now in eSocial, it is best to always get the S-1000 event (

20.12.2018 / 18:15