Assinar Rps e Lote na NFSe

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Eroni
Usuário Nível 1
Usuário Nível 1
Mensagens: 20
Registrado em: 18 Mai 2015 09:15
Localização: Criciuma/SC

Assinar Rps e Lote na NFSe

Mensagem por Eroni »

Bom dia a todos,

Alguém já conseguiu fazer mais de uma assinatura no mesmo xml como exigem algumas prefeituras?

Tenho desenvolvido a NFSe para algumas cidades, derivando do projeto HBNFe, mas estou tendo problema ao assinar o rps o lote, já tentei varias opções:

Assinar somente o rps - Ok, assinatura válida, mas o provedor não aceita
Assinar somente o lote - Ok, o provedor aceita, mas ao pegar o retorno, retorna mensagem de rejeição por falta de assinatura no rps
Assinar os dois separadamente e depois juntar em um só xml. A assinatura fica inválida. Tanto o validador de assinaturas da receita quanto o provedor rejeitam.

Tanto o rps assinado individualmente quanto e o lote assinado individualmente são aceitos pelo validador da receita, isto quer dizer que a assinatura em si é válida, acho que o problema é que quando vai ser assinado o xml, a assinatura é feita somente no rps, pois o mesmo está antes do local reservado para o lote, pode ser na hora de posicionar a tag correta para a assinatura, alguém sabe como fazer isso?

O projeto está sendo portado para vários provedores, quando estiver pronto pretendo disponibilizar aqui.

Abraços a todos.
xHarbour 1.2.1 FiveWin 1209 SQLRDD-SQLEX-xHarbour.org-March2010-build31
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Esse tipo de pergunta já passou por aqui.

a nota é algo como <nfe>sdfdsdd</nfe>
o lote é algo como <lote>dsfsfsdfd<nfe>..</nfe><nfe></nfe></lote>

é uma assinatura dentro de cada bloco <nfe>, e depois uma assinatura no bloco <lote>

Para a rotina de assinatura é passada a URI que indica o bloco a ser assinado.
Sua rotina de assinatura precisa tratar diferente quando o bloco for <nfe> ou quando o bloco for <lote>

Confirme na rotina de assinatura como é obtida a posição para o bloco <Signature>
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Eroni
Usuário Nível 1
Usuário Nível 1
Mensagens: 20
Registrado em: 18 Mai 2015 09:15
Localização: Criciuma/SC

Assinar Rps e Lote na NFSe

Mensagem por Eroni »

Obrigado pela resposta José.

A posição obtida é assim:

xmldsig:signature := oDOMDoc:selectSingleNode( './/ds:Signature' )


Mas não sei se está correto, o xml é o abaixo:

<?xml version="1.0"?><EnviarLoteRpsEnvio xmlns="http://www.abrasf.org.br/nfse.xsd"><LoteRps Id="lote220" versao="1.00">
<NumeroLote>220</NumeroLote>
<Cnpj>19337655000188</Cnpj>
<InscricaoMunicipal>09340450014</InscricaoMunicipal>
<QuantidadeRps>1</QuantidadeRps>
<ListaRps>
<Rps>
<InfRps Id="RPS1">
<IdentificacaoRps>
<Numero>1</Numero>
<Serie>1</Serie>
<Tipo>1</Tipo>
</IdentificacaoRps>
<DataEmissao>2016-01-26T10:38:58</DataEmissao>
<NaturezaOperacao>1</NaturezaOperacao>
<RegimeEspecialTributacao>6</RegimeEspecialTributacao>
<OptanteSimplesNacional>1</OptanteSimplesNacional>
<IncentivadorCultural>2</IncentivadorCultural>
<Status>1</Status>
<Servico>
<Valores>
<ValorServicos>100.00</ValorServicos>
<ValorDeducoes>0.00</ValorDeducoes>
<ValorPis>0.00</ValorPis>
<ValorCofins>0.00</ValorCofins>
<ValorInss>0.00</ValorInss>
<ValorIr>0.00</ValorIr>
<ValorCsll>0.00</ValorCsll>
<IssRetido>1</IssRetido>
<ValorIss>2.79</ValorIss>
<OutrasRetencoes>0.00</OutrasRetencoes>
<Aliquota>0.0279</Aliquota>
<DescontoIncondicionado>0.00</DescontoIncondicionado>
<DescontoCondicionado>0.00</DescontoCondicionado>
</Valores>
<ItemListaServico>17.19</ItemListaServico>
<CodigoTributacaoMunicipio>171900188</CodigoTributacaoMunicipio>
<Discriminacao>CONTABILIDADE SERVICO </Discriminacao>
<CodigoMunicipio>3106200</CodigoMunicipio>
</Servico>
<Prestador> <Cnpj>19337655000188</Cnpj> <InscricaoMunicipal>09340450014</InscricaoMunicipal></Prestador>
<Tomador> <IdentificacaoTomador> <CpfCnpj> <Cnpj>04280451000180</Cnpj> </CpfCnpj> <InscricaoMunicipal>01641950010</InscricaoMunicipal> </IdentificacaoTomador> <RazaoSocial>TEC SOLUCOES CORPORATIVAS LTDA</RazaoSocial> <Endereco> <Endereco>RUA ADALBERTO FERRAZ</Endereco> <Numero>42</Numero> <Bairro>LAGOINHA</Bairro> <CodigoMunicipio>3106200</CodigoMunicipio> <Uf>MG</Uf> <Cep>31210020</Cep> </Endereco>
</Tomador>
</InfRps>
<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/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#RPS1">
<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/2000/09/xmldsig#sha1"/>
<DigestValue></DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo></KeyInfo>
</Signature>
</Rps>
</ListaRps>
</LoteRps>
<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/2000/09/xmldsig#rsa-sha1"/><Reference URI="#lote220">
<Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envel ... <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>
</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo></KeyInfo>
</Signature>
</EnviarLoteRpsEnvio>

Alguma idéia de onde preciso modificar?

Grato.
xHarbour 1.2.1 FiveWin 1209 SQLRDD-SQLEX-xHarbour.org-March2010-build31
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Assinar Rps e Lote na NFSe

Mensagem por Kapiaba »

bom dia Eroni, use este leitor de XML, para validar o seu .XML.

https://leitorxmlnfe.websiteseguro.com/

Veja se esse serve para você também:

http://www.semx.com.br/

Abs
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

1. Separar cada nota, e assinar cada nota
2. Juntar tudo como está aí
3. Assinar o lote.

A assinatura:
A rotina de assinatura costuma gerar a assinatura preenchida, e precisa trocar o bloco de assinatura vazio, pelo da assinatura preenchida.

Acabei de acrescentar a última linha aqui mas não testei, serve como base de comparação pras diversas assinaturas:

Código: Selecionar todos

   aDelimitadores := { ;
      { "<enviMDFe",   "</MDFe></enviMDFe>" }, ;
      { "<eventoMDFe", "</eventoMDFe>" }, ;
      { "<eventoCTe",  "</eventoCTe>" }, ;
      { "<infMDFe",    "</MDFe>" }, ;
      { "<infCte",     "</CTe>" }, ;
      { "<infNFe",     "</NFe>" }, ;
      { "<infDPEC",    "</envDPEC>" }, ;
      { "<infInut",    "<inutNFe>" }, ;
      { "<infCanc",    "</cancNFe>" }, ;
      { "<infInut",    "</inutNFe>" }, ;
      { "<infEvento",  "</evento>" }, ;
      { "<infPedidoCancelamento", "</Pedido>" }, ; // NFSE ABRASF Cancelamento
      { "<infRps",     "</Rps>" }, ;               // NFSE ABRASF
      { "<LoteRps",    "</EnviarLoteRpsEnvio>" } }            // Lote NFSE
Nota: supondo que realmente sejam necessárias duas assinaturas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Eroni
Usuário Nível 1
Usuário Nível 1
Mensagens: 20
Registrado em: 18 Mai 2015 09:15
Localização: Criciuma/SC

Assinar Rps e Lote na NFSe - Resolvido

Mensagem por Eroni »

Obrigado ao Kapi e ao José pelas dicas, mas o xml está ok, testei inclusive pelo link que o kapi mencionou.

Quanto ao procedimento descrito pelo José, é o que eu havia fazendo, porém o provedor recusa com a mensagem de assinatura inválida.
Se eu assinar somente o lote o provedor recebe, porém ao pegar o retorno também há a recusa de falta de assinatura no rps, então, infelizmente, é obrigatório as duas assinaturas, em todos os exemplos de manuais que eu vi constam duas assinaturas.
O problema é fazer a assinatura de um documento só em dois locais, esse é o ponto que está a dificuldade.
xHarbour 1.2.1 FiveWin 1209 SQLRDD-SQLEX-xHarbour.org-March2010-build31
Eroni
Usuário Nível 1
Usuário Nível 1
Mensagens: 20
Registrado em: 18 Mai 2015 09:15
Localização: Criciuma/SC

Assinar Rps e Lote na NFSe

Mensagem por Eroni »

Resolvido com a mudança no processo de pegar o bloco de assinatura, alternando-se entre os nodes de assinaturas. Se alguém passar pelo mesmo problema entre em contato para mais detalhes.

Abraço a todos.
xHarbour 1.2.1 FiveWin 1209 SQLRDD-SQLEX-xHarbour.org-March2010-build31
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Olhei de novo a rotina, e eu tinha invertido a análise.
Com a inversão, sempre ia considerar nota, e a assinatura iria entrar na primeira nota.
spedsefaz.png
https://github.com/JoseQuintas/sefazclass

Nota: A rotina não assina nota dentro de lote. Precisa fazer cada nota individualmente, e só no final juntar tudo e assinar o lote.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
quelps
Usuário Nível 1
Usuário Nível 1
Mensagens: 1
Registrado em: 17 Nov 2017 16:30
Localização: Araguaina-TO

Assinar Rps e Lote na NFSe

Mensagem por quelps »

Boa tarde Eroni, estou com o mesmo o problema na assinatura do RPS e do LoteRPS, estou fazendo a assinatura pelo Capicom.
tem como vc passar um exemplo de como vc fez para conseguir as duas assinaturas no mesmo XML?
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Estou tentando entender, porque parece que a segunda parte desta rotina não serve pra nada com uma assinatura, mas estraga se tiver várias assinaturas.
Não lembro porque a coloquei.

Código: Selecionar todos

STATIC FUNCTION AssinaAjustaAssinado( cXml )

   LOCAL nPosIni, nPosFim, nP, nResult

      cXml := StrTran( cXml, Chr(10), "" )
      cXml := StrTran( cXml, Chr(13), "" )
      nPosIni     := At( [<SignatureValue>], cXml ) + Len( [<SignatureValue>] )
      cXml := Substr( cXml, 1, nPosIni - 1 ) + StrTran( Substr( cXml, nPosIni, Len( cXml ) ), " ", "" )
      nPosIni     := At( [<X509Certificate>], cXml ) - 1
      nP          := At( [<X509Certificate>], cXml )
      nResult     := 0
      DO WHILE nP <> 0
         nResult := nP
         nP      := hb_At( [<X509Certificate>], cXml, nP + 1 )
      ENDDO
      nPosFim     := nResult
      cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )

      RETURN cXml
Esta parte aqui:

Código: Selecionar todos

      nPosIni     := At( [<X509Certificate>], cXml ) - 1
      nP          := At( [<X509Certificate>], cXml )
      nResult     := 0
      DO WHILE nP <> 0
         nResult := nP
         nP      := hb_At( [<X509Certificate>], cXml, nP + 1 )
      ENDDO
      nPosFim     := nResult
      cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )
E na primeira parte, seria trocar At() por Rat(), assim pega a última assinatura, e não a primeira.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Sinceramente não lembro se tem utilidade.... rs
Na dúvida, achei um meio-termo:
usei hb_At() pra achar o último bloco de <SignatureValue> e a partir daí vai fazer o mesmo processo de antes.
Desse jeito, não faz diferença pra uma assinatura, mas faz se tiverem várias assinaturas no XML, porque só vai mexer na última, que seria do lote.

Código: Selecionar todos

STATIC FUNCTION AssinaAjustaAssinado( cXml )

   LOCAL nPosIni, nPosFim, nP, nResult

      cXml    := StrTran( cXml, Chr(10), "" )
      cXml    := StrTran( cXml, Chr(13), "" )
      nPosIni := RAt( [<SignatureValue>], cXml ) + Len( [<SignatureValue>] )
      cXml    := Substr( cXml, 1, nPosIni - 1 ) + StrTran( Substr( cXml, nPosIni, Len( cXml ) ), " ", "" )
      nPosIni := hb_At( [<X509Certificate>], cXml, nPosIni ) - 1
      nP      := nPosIni + 1
      nResult := 0
      DO WHILE nP <> 0
         nResult := nP
         nP      := hb_At( [<X509Certificate>], cXml, nP + 1 )
      ENDDO
      nPosFim := nResult
      IF nPosIni > 0 .AND. nPosFim > 0
         cXml := Substr( cXml, 1, nPosIni ) + Substr( cXml, nPosFim, Len( cXml ) )
      ENDIF

      RETURN cXml
Testar a compilação e subir pro github.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Acho que por aqui fica mais nítido o que foi alterado.

https://github.com/JoseQuintas/sefazcla ... bac7ea53ee
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Aproveitei pra reduzir fonte..... rs

Eu criava nResult pra depois colocar em nPosfim... ué... só usar nPosFim de uma vez, pra que outra variável.... rs

Essas coisas é que dá pra gente ver conforme vai dividindo em rotinas menores.
No começo a assinatura era uma rotina gigante.... rs
E retirei o IF que acrescentei antes: nunca vai ser menor que 1, não precisa testar.

https://github.com/JoseQuintas/sefazcla ... 7d851829a2
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Assinar Rps e Lote na NFSe

Mensagem por sygecom »

Eroni escreveu:Resolvido com a mudança no processo de pegar o bloco de assinatura, alternando-se entre os nodes de assinaturas. Se alguém passar pelo mesmo problema entre em contato para mais detalhes.

Abraço a todos.
Eroni, bom dia.
Estou com mesmo problema aqui na NFSe de NATAL-RN, poderia postar um exemplo de como resolveu ou como resolveu ?
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Assinar Rps e Lote na NFSe

Mensagem por JoséQuintas »

Geralmente usamos At() pra achar o bloco de assinatura, isso pega o primeiro bloco.
Normal, já que cada nota tem seu próprio bloco.
No caso do lote, já vai existir uma assinatura da nota, então tem que usar Rat() pra localizar o último bloco que é do lote.
Se não fizer isso, vai pegar bloco da nota e não do lote.

Aliás... talvez melhor pegar sempre o último, já que quando só tem um, tanto faz se pesquisar a partir do início ou do final.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder