Estou implementando o eSocial no meu sistema e meu prazo já está esgotado.
Preciso enviar o evento S1000 (Inicial). Já estruturei todo o xml mas quando envio, recebo a mensagem :
Codigo = 142
Descricao = Assinatura do evento inválida. Ações Sugeridas: Verificar se houve alteração do evento após a assinatura. Verificar a validade da assinatura.
Localizacao = /eSocial/Signature
Com muitas pesquisas para assinar com SHA256 (diferente da NFe que é SHA1), cheguei ao código abaixo.
Pergunto:
1) Tem algo errado no código ?
2) A base da assinatura (pedaço do xml) está correta ? (O manual diz que a assinatura tem que ser sobre o Evento)
3) Tem como eu checar se a assinatura está correta antes de enviar ? (Pela string da assinatura achar a base que foi assinada ?)
Alguém já passou por esse erro ?
Pode dar uma dica ?
Desde já, agradeço, lembrando: é URGENTE.
------------------------------------------------------------------código
xml :=
<?xml version="1.0"?>
<eSocial xmlns="http://www.esocial.gov.br/schema/evt/evtInfoEmpregador/v02_04_02">
<evtInfoEmpregador Id="ID1290588510000002018070122564800001">
<ideEvento>
<tpAmb>2</tpAmb>
<procEmi>0</procEmi>
<verProc>1.0</verProc>
</ideEvento>
<ideEmpregador>
<tpInsc>1</tpInsc>
<nrInsc>19052251</nrInsc>
</ideEmpregador>
<infoEmpregador>
<inclusao>
<idePeriodo>
<iniValid>2018-05</iniValid>
</idePeriodo>
<infoCadastro>
<nmRazao>LOJA DO COMERCIO LTDA</nmRazao>
<classTrib>01</classTrib>
<natJurid>2305</natJurid>
<indCoop>0</indCoop>
<indConstr>0</indConstr>
<indDesFolha>0</indDesFolha>
<indOptRegEletron>0</indOptRegEletron>
<indEntEd>N</indEntEd>
<indEtt>N</indEtt>
<contato>
<nmCtt>JOAO DA SILVA</nmCtt>
<cpfCtt>02223323232</cpfCtt>
<foneFixo>6239412233</foneFixo>
<foneCel>62999999999</foneCel>
<email>joaoorganizacao@yahoo.com.br</email>
</contato>
<softwareHouse>
<cnpjSoftHouse>22332323232357</cnpjSoftHouse>
<nmRazao>Sistemas Informatica Ltda</nmRazao>
<nmCont>Joao Mensdes Mendonca</nmCont>
<telefone>6232559090</telefone>
<email>suporte@sistemasgestaox.com.br</email>
</softwareHouse>
<infoComplementares>
<situacaoPJ>
<indSitPJ>0</indSitPJ>
</situacaoPJ>
</infoComplementares>
</infoCadastro>
</inclusao>
</infoEmpregador>
</evtInfoEmpregador>
</eSocial>
sig :=
<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>'
xmlassinado := Minha_Assina( Xml , Sig )
*************************************************************
Function Minha_Assina(Veio_Xml , Veio_Sig )
LOCAL DigestValue,aAss,SignatureValue, X509
cXML := PegaTag( Veio_XML , "evtInfoEmpregador")
// Alernativa 1
DigestValue := _HashCapicom( cXml )
// Alernativa 2 (Nativa do Harbour)
DigestValue := hb_sha256( cXml )
aAss := _SignatureCapicom( DigestValue )
If aAss[1]==NIL
Return NIL
Endif
SignatureValue := aAss[1]
X509 := aAss[2]
cXmlSig := _InsereDadosTag( cXmlSig, "DigestValue" , DigestValue )
cXmlSig := _InsereDadosTag( cXmlSig, "SignatureValue" , SignatureValue )
cXmlSig := _InsereDadosTag( cXmlSig, "X509Certificate" , x509 )
cTexto := SUBS( ccXML ,1,AT('</eSocial>', ccXML )-1)
cTexto += cXMLSig
cTexto := cTexto + '</eSocial>'
Return( cTexto )
FUNCTION _SignatureCapicom( DigestValue, Cert, Encode )
LOCAL SignedData, CertBase64, Signer, sRet, TimeAttrib
Signer := win_oleCreateObject("CAPICOM.Signer.2") //versao 2
IF Cert = NIL
Cert := _SelecionaCertificadoCapicom()
IF Cert = NIL
RETURN{ NIL,NIL}
ENDIF
Signer:Certificate := cert
ELSE
Signer:Certificate := cert:DefaultInterface
ENDIF
IF !(Signer:Certificate:HasPrivateKey ;
.and. DToS(Signer:Certificate:ValidFromDate) <= DToS(Date()) ;
.and. DToS(Signer:Certificate:ValidToDate) >= DToS(Date()) )
RETURN NIL
ENDIF
Signer:Options := CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
CertBase64 := Signer:Certificate:Export(CAPICOM_ENCODE_BASE64)
CertBase64 := Trim(StrTran(certBase64, Chr(13) + Chr(10), ''))
TimeAttrib := win_oleCreateObject("CAPICOM.Attribute")
TimeAttrib:Name := CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
TimeAttrib:Value = DateTime()
Signer:AuthenticatedAttributes:Add(TimeAttrib)
SignedData := win_oleCreateObject("CAPICOM.SignedData.1")
SignedData:Content := DigestValue
sRet := SignedData:Sign(Signer, .F., Encode)
RETURN{ sRet, CertBase64 }
FUNCTION _HashCapicom( sTexto, AlgoritimoHash )
LOCAL objHash
IF sTexto = NIL
sTexto := DToS(Date()) + Time()
ENDIF
IF AlgoritimoHash = NIL
AlgoritimoHash := CAPICOM_HASH_ALGORITHM_SHA_256
ENDIF
objHash := win_oleCreateObject("CAPICOM.HashedData.1")
objHash:Algorithm := AlgoritimoHash
objHash:Hash( sTexto )
RETURN objHash:Value
FUNCTION _SelecionaCertificadoCapicom()
LOCAL MyStore, Certificates , oError
MyStore := CreateObject("CAPICOM.Store")
MyStore := win_oleCreateObject("CAPICOM.Store")
MyStore:Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY )
TRY
Certificates := MyStore:Certificates:Select("Selecione um certificado digital","Algoritimo de Assinatura SHA256RSA")
CATCH oError
MsgStop('Não foi possível carregar objeto XMLHTTPServer', 'Erro')
RETURN NIL
END
IF MyStore:certificates:Count = 0
RETURN NIL
ENDIF
RETURN( certificates:Item(1) )
FUNCTION _InsereDadosTag( cXml, cTag, cDados )
LOCAL nPosIni, nPosFim, cPart1, cPart2
LOCAL cRetorno
cRetorno := cXml
nPosIni := At( "<"+cTag,cXml )
IF nPosIni == 0
RETURN( cRetorno )
ENDIF
nPosIni := nPosIni + Len( cTag ) + 1
cPart1 := SubStr( cXml,1,nPosIni )
nPosFim := At( "</"+cTag+">",cXml )
cPart2 := SubStr( cXml,nPosFim, Len( cXml ) )
cRetorno := cPart1 + cDados + cPart2
RETURN( cRetorno )
Function pegaTag(cXML, cTag)
LOCAL cRetorno, cTagInicio,cTagFim
cTagInicio := "<"+cTag //+">"
cTagFim := "</"+cTag+">"
cRetorno := SUBS( cXML, AT(cTagInicio,cXML)+LEN(cTagInicio)+1, AT(cTagFim,cXML)-(AT(cTagInicio,cXML)+LEN(cTagInicio)+1) )
RETURN(cRetorno)
***************************