Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 2611 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

[Solved] Assinatura A3 com SHA256.

 

Uma opção que achei junto ao um amigo meu que é programador C# foi criar uma DLL em C# para fazer a assinatura. Basicamente, a gente manda o XML e a DLL devolve assinada, apenas isso. A DLL foi feita baseada no CertFly e é consumida pelo o método 'Assinar' da classe 'TDFeSSLXmlSignClass' que fica localizada no arquivo 'ACBrDFeSSL'.

[Código aberto]

https://github.com/tiagopsilva/eSocialSignature

 

[Como usar]

No arquivo 'ACBrDFeSSL' coloque 'eSocialSignature' no 'uses' da 'interface'. Depois disso apague tudo que está no método 'Assinar' e substitua por esse código:

var
  xml: PAnsiChar;
begin
   FpDFeSSL.SetSSLXmlSignLib(xsXmlSec);
   FpDFeSSL.SSLCryptLib := cryCapicom;

   xml := PAnsiChar(AnsiString(ConteudoXML));
   TESocialSignature.SignSHA256Ansi(xml, PAnsiChar(AnsiString(infElement)),
                                         PAnsiChar(AnsiString(FpDFeSSL.NumeroSerie)),
                                         PAnsiChar(AnsiString(FpDFeSSL.Senha)));
   Result := string(AnsiString(xml));

 

Isso é a única coisa que precisa ser alterada no plugin da ACBReSocial. Porém, é necessário definir a 'SSLLib' para 'libCustom' nas configurações do 'ACBreSocial', exemplo:

If ( Obj.Modelo = A3 ) Then
         Begin
            If Not FConsultar Then
               AACBreSocial.Configuracoes.Geral.SSLLib := libCustom
            Else
               AACBreSocial.Configuracoes.Geral.SSLLib := libCapicom;

            AACBreSocial.Configuracoes.Certificados.NumeroSerie := Obj.NumeroSerie;
            AACBreSocial.SSL.CarregarCertificado;
         End;

 

Para facilitar, apenas uso a 'libCustom' na hora de exportar já que o problema estava na assinatura do XML. Quando eu consulto eu já deixo o plugin fazer o processo dele normalmente, já que, na consulta não é necessário a assinatura digital. Porém, no código da ACBR pede o carregamento do certificado, e eu estava com problemas no método 'EnviarDados' da classe 'TDFeWebService' que fica no arquivo 'ACBrDFeWebService'. Quando o método executa '(FPDFeOwner.SSL.CertDataVenc < Now)' da problemas, pois, o 'CertDataVenc' vem com o valor default e não do certificado. Então preferi fazer essa estratégia com a flag do que sobrescrever mais o código original.

  • Curtir 1
Postado
23 horas atrás, Jeihcio Francis disse:

[Solved] Assinatura A3 com SHA256.

 

Uma opção que achei junto ao um amigo meu que é programador C# foi criar uma DLL em C# para fazer a assinatura. Basicamente, a gente manda o XML e a DLL devolve assinada, apenas isso. A DLL foi feita baseada no CertFly e é consumida pelo o método 'Assinar' da classe 'TDFeSSLXmlSignClass' que fica localizada no arquivo 'ACBrDFeSSL'.

[Código aberto]

https://github.com/tiagopsilva/eSocialSignature

 

[Como usar]

No arquivo 'ACBrDFeSSL' coloque 'eSocialSignature' no 'uses' da 'interface'. Depois disso apague tudo que está no método 'Assinar' e substitua por esse código:

var
  xml: PAnsiChar;
begin
   FpDFeSSL.SetSSLXmlSignLib(xsXmlSec);
   FpDFeSSL.SSLCryptLib := cryCapicom;

   xml := PAnsiChar(AnsiString(ConteudoXML));
   TESocialSignature.SignSHA256Ansi(xml, PAnsiChar(AnsiString(infElement)),
                                         PAnsiChar(AnsiString(FpDFeSSL.NumeroSerie)),
                                         PAnsiChar(AnsiString(FpDFeSSL.Senha)));
   Result := string(AnsiString(xml));

 

Isso é a única coisa que precisa ser alterada no plugin da ACBReSocial. Porém, é necessário definir a 'SSLLib' para 'libCustom' nas configurações do 'ACBreSocial', exemplo:

If ( Obj.Modelo = A3 ) Then
         Begin
            If Not FConsultar Then
               AACBreSocial.Configuracoes.Geral.SSLLib := libCustom
            Else
               AACBreSocial.Configuracoes.Geral.SSLLib := libCapicom;

            AACBreSocial.Configuracoes.Certificados.NumeroSerie := Obj.NumeroSerie;
            AACBreSocial.SSL.CarregarCertificado;
         End;

 

Para facilitar, apenas uso a 'libCustom' na hora de exportar já que o problema estava na assinatura do XML. Quando eu consulto eu já deixo o plugin fazer o processo dele normalmente, já que, na consulta não é necessário a assinatura digital. Porém, no código da ACBR pede o carregamento do certificado, e eu estava com problemas no método 'EnviarDados' da classe 'TDFeWebService' que fica no arquivo 'ACBrDFeWebService'. Quando o método executa '(FPDFeOwner.SSL.CertDataVenc < Now)' da problemas, pois, o 'CertDataVenc' vem com o valor default e não do certificado. Então preferi fazer essa estratégia com a flag do que sobrescrever mais o código original.

funcionou 100%.

Parabéns.

  • Curtir 1
Postado
2 horas atrás, LUIZTEC disse:

Substitui o arquivo ACBrDFeSSL.pas e quando vai assinar mostra o erro "External exception E0434352", linha do Esocialsignature.dll ->   proc(AXml, ANodeToSign, ASerialNumber, APassword);

Postado

Acabei de testar e eu mesmo tive problemas, quando eu tento exportar um lote com mais de um evento está dando a seguinte mensagem de erro: "Certificado não permite Exportar Chave Privada.". Ele acontece no arquivo 'ACBrDFeWinCrypt' no método "ExportCertContextToPFXData" na linha 681, onde tem:

if not PFXExportCertStoreEx( AStore, PFXBlob,
                                 LPCWSTR(WideString( APass )),
                                 Nil, dwFlags) then
      raise EACBrDFeExceptionNoPrivateKey.Create('Certificado não permite Exportar Chave Privada.');

 

Alguém sabe o motivo? Estranho, por que certificado A3 não tem PFX, então não era para está chamando todo esse processo....

Postado
17 horas atrás, Jeihcio Francis disse:

Acabei de testar e eu mesmo tive problemas, quando eu tento exportar um lote com mais de um evento está dando a seguinte mensagem de erro: "Certificado não permite Exportar Chave Privada.". Ele acontece no arquivo 'ACBrDFeWinCrypt' no método "ExportCertContextToPFXData" na linha 681, onde tem:

if not PFXExportCertStoreEx( AStore, PFXBlob,
                                 LPCWSTR(WideString( APass )),
                                 Nil, dwFlags) then
      raise EACBrDFeExceptionNoPrivateKey.Create('Certificado não permite Exportar Chave Privada.');

 

Alguém sabe o motivo? Estranho, por que certificado A3 não tem PFX, então não era para está chamando todo esse processo....

Minhas configurações estão assim e está funcionando normalmente, até para vários eventos: (nao usei libcustom)

  VESocial.Configuracoes.Geral.SSLLib        := libOpenSSL;  
  VESocial.Configuracoes.Geral.SSLHttpLib    := httpWinHttp; 
  VESocial.Configuracoes.Geral.SSLCryptLib   := cryWinCrypt; 
  VESocial.Configuracoes.Geral.SSLXmlSignLib := xsXmlSec;   

  VESocial.SSL.SelecionarCertificado;

 

Postado
1 hora atrás, LUIZTEC disse:

Minhas configurações estão assim e está funcionando normalmente, até para vários eventos: (nao usei libcustom)

  VESocial.Configuracoes.Geral.SSLLib        := libOpenSSL;  
  VESocial.Configuracoes.Geral.SSLHttpLib    := httpWinHttp; 
  VESocial.Configuracoes.Geral.SSLCryptLib   := cryWinCrypt; 
  VESocial.Configuracoes.Geral.SSLXmlSignLib := xsXmlSec;   

  VESocial.SSL.SelecionarCertificado;

 

Utilizando o seu ACBrDFeSSL.pas dá erro ao compilar o ACBr_DFeComum, segue o erro abaixo:

    function ValidarHash( const AStream : TStream;
       const Digest: TSSLDgst;
       const Hash: AnsiString;
       const Assinado: Boolean =  False): Boolean; override;
 

Erro no ACBrDFeWinCrypt.pas

Postado

Eu acabei resolvendo o problema que mencionei acima da seguinte forma: 

 

Configurações do componente:

 

If ( Obj.Modelo = A3 ) Then
         Begin
            If FConsultar Then
               AACBreSocial.Configuracoes.Geral.SSLLib := libCapicom
            Else
               AACBreSocial.Configuracoes.Geral.SSLLib := libCustom;

            AACBreSocial.Configuracoes.Geral.SSLXmlSignLib := xsNone;
            AACBreSocial.Configuracoes.Certificados.NumeroSerie := Obj.NumeroSerie;
            AACBreSocial.SSL.CarregarCertificado;
         End;

 

Obs: Eu sei que por default o 'SSLXmlSignLib' vem 'xsNone', mas eu quis deixar explicitamente no código do meu controller que é obrigatório setar esse valor no atributo. 

 

Depois e antes de enviar eu faço:

 

{ Assinatura digital }
ACBreSocial1.AssinarEventos;

{ Enviar dados ao webservice }
ACBreSocial1.Configuracoes.Geral.SSLXmlSignLib := xsXmlSec;
ACBreSocial1.Enviar(getTipoGrupo(nTabela));

 

Antes de enviar é obrigatório setar 'xsXmlSec'  para a propriedade 'SSLXmlSignLib', pois no método 'Enviar' da classe 'TACBreSocial' que fica dentro do arquivo 'ACBReSocial' existe a seguinte verificação: 

 

if SSL.SSLXmlSignLib <> xsXmlSec then
    raise EACBreSocialException.Create('Necessário DigestMethod Algorithm = sha256 -> SSLLib = libOpenSSL'); 

 

Essas configurações eu fiz no meu código da minha aplicação, já no componente da ACBR tive que fazer as seguintes alterações no arquivo 'ACBrDFeSSL':

 

Método 'Assinar' da classe 'TDFeSSLXmlSignClass':

 

function TDFeSSLXmlSignClass.Assinar(const ConteudoXML, docElement,
  infElement: String; SignatureNode: String; SelectionNamespaces: String;
  IdSignature: String; IdAttr: String): String;
var
  xml: PAnsiChar;
begin
   FpDFeSSL.SSLCryptLib := cryCapicom;

   xml := PAnsiChar(AnsiString(ConteudoXML));
   TESocialSignature.SignSHA256Ansi(xml, PAnsiChar(AnsiString(infElement)),
                                         PAnsiChar(AnsiString(FpDFeSSL.NumeroSerie)),
                                         PAnsiChar(AnsiString(FpDFeSSL.Senha)));
   Result := string(AnsiString(xml));
end;

 

e no método 'Validar' dessa mesma classe:

 

function TDFeSSLXmlSignClass.Validar(const ConteudoXML, ArqSchema: String; out
  MsgErro: String): Boolean;
var
  DFeSSL: TDFeSSL;
begin
   DFeSSL := TDFeSSL.Create;
   Try
      DFeSSL.SetSSLXmlSignLib(xsXmlSec);
      Result := DFeSSL.Validar(ConteudoXML, ArqSchema, MsgErro);
   Finally
      DFeSSL.Free;
   End;
end;

 

Essas foram as unicas alterações que fiz para resolver o problema....

Postado
39 minutos atrás, Jeihcio Francis disse:

Eu acabei resolvendo o problema que mencionei acima da seguinte forma: 

 

Configurações do componente:

 

If ( Obj.Modelo = A3 ) Then
         Begin
            If FConsultar Then
               AACBreSocial.Configuracoes.Geral.SSLLib := libCapicom
            Else
               AACBreSocial.Configuracoes.Geral.SSLLib := libCustom;

            AACBreSocial.Configuracoes.Geral.SSLXmlSignLib := xsNone;
            AACBreSocial.Configuracoes.Certificados.NumeroSerie := Obj.NumeroSerie;
            AACBreSocial.SSL.CarregarCertificado;
         End;

 

Obs: Eu sei que por default o 'SSLXmlSignLib' vem 'xsNone', mas eu quis deixar explicitamente no código do meu controller que é obrigatório setar esse valor no atributo. 

 

Depois e antes de enviar eu faço:

 

{ Assinatura digital }
ACBreSocial1.AssinarEventos;

{ Enviar dados ao webservice }
ACBreSocial1.Configuracoes.Geral.SSLXmlSignLib := xsXmlSec;
ACBreSocial1.Enviar(getTipoGrupo(nTabela));

 

Antes de enviar é obrigatório setar 'xsXmlSec'  para a propriedade 'SSLXmlSignLib', pois no método 'Enviar' da classe 'TACBreSocial' que fica dentro do arquivo 'ACBReSocial' existe a seguinte verificação: 

 

if SSL.SSLXmlSignLib <> xsXmlSec then
    raise EACBreSocialException.Create('Necessário DigestMethod Algorithm = sha256 -> SSLLib = libOpenSSL'); 

 

Essas configurações eu fiz no meu código da minha aplicação, já no componente da ACBR tive que fazer as seguintes alterações no arquivo 'ACBrDFeSSL':

 

Método 'Assinar' da classe 'TDFeSSLXmlSignClass':

 

function TDFeSSLXmlSignClass.Assinar(const ConteudoXML, docElement,
  infElement: String; SignatureNode: String; SelectionNamespaces: String;
  IdSignature: String; IdAttr: String): String;
var
  xml: PAnsiChar;
begin
   FpDFeSSL.SSLCryptLib := cryCapicom;

   xml := PAnsiChar(AnsiString(ConteudoXML));
   TESocialSignature.SignSHA256Ansi(xml, PAnsiChar(AnsiString(infElement)),
                                         PAnsiChar(AnsiString(FpDFeSSL.NumeroSerie)),
                                         PAnsiChar(AnsiString(FpDFeSSL.Senha)));
   Result := string(AnsiString(xml));
end;

 

e no método 'Validar' dessa mesma classe:

 

function TDFeSSLXmlSignClass.Validar(const ConteudoXML, ArqSchema: String; out
  MsgErro: String): Boolean;
var
  DFeSSL: TDFeSSL;
begin
   DFeSSL := TDFeSSL.Create;
   Try
      DFeSSL.SetSSLXmlSignLib(xsXmlSec);
      Result := DFeSSL.Validar(ConteudoXML, ArqSchema, MsgErro);
   Finally
      DFeSSL.Free;
   End;
end;

 

Essas foram as unicas alterações que fiz para resolver o problema....

Eu fiz todas essas alterações e voltou a dar o mesmo erro:

erro "External exception E0434352", linha do Esocialsignature.dll ->   proc(AXml, ANodeToSign, ASerialNumber, APassword);

Postado
50 minutes ago, fabibona said:

Eu fiz todas essas alterações e voltou a dar o mesmo erro:

erro "External exception E0434352", linha do Esocialsignature.dll ->   proc(AXml, ANodeToSign, ASerialNumber, APassword);

Então, verifica se o A3 está conectado corretamente. Só use essa dll se for para o a3, o a1 usa o próprio ACBR

Postado
Em 26/12/2017 at 15:27, fabibona disse:

Substitui o arquivo ACBrDFeSSL.pas e quando vai assinar mostra o erro "External exception E0434352", linha do Esocialsignature.dll ->   proc(AXml, ANodeToSign, ASerialNumber, APassword);

Há dois arquivos de DLL que precisam ser adicionados na pasta do executável do seu projeto. Está colocando as duas?
E posta o trecho do seu código que levanta a exceção ou um exemplo de como você está recebendo esse erro.

Postado
36 minutos atrás, tiago.prs disse:

Há dois arquivos de DLL que precisam ser adicionados na pasta do executável do seu projeto. Está colocando as duas?
E posta o trecho do seu código que levanta a exceção ou um exemplo de como você está recebendo esse erro.

Realmente o problema foi esse, faltou colocar na pasta do executável o arquivo Security.Cryptography.dll , muito obrigado pela dica e agradeço também a todos e ao Jeihcio pela elaboração do projeto, agora esta funcionando perfeitamente.

Postado
Em 05/01/2018 at 07:48, juuninho disse:

Essas soluções apresentadas ainda caem no problema que o Juliomar tinha citado em algum tópico por aí? Em relação a dependência do C# nas máquinas, não funcionamento no windows XP, etc, ou está "independente" ?

Obrigado!

A assinatura do A1 e A3 estão funcionando perfeitamente. A minha dúvida é que a assinatura do A3 é muito mais lenta que do A1. Estou assinando 80 eventos, no A1 leva segundos para fazer, já no A3 leva mais de 5 minutos.  Isso é normal, já que a assinatura do A3 é feita pelo pendrive?

 

Postado
12 minutos atrás, LUIZTEC disse:

A assinatura do A1 e A3 estão funcionando perfeitamente. A minha dúvida é que a assinatura do A3 é muito mais lenta que do A1. Estou assinando 80 eventos, no A1 leva segundos para fazer, já no A3 leva mais de 5 minutos.  Isso é normal, já que a assinatura do A3 é feita pelo pendrive?

 

Isso mesmo @LUIZTEC... A3 é bem mais lento devido a necessidade de acesso a hardware externo para ter acesso a chave privada. o qual não ocorre com A1 haja vista que o mesmo já tem a chave privada quando exportada ao arquivo.

A3 oferece maior segurança...mais perde em performance. 

Postado
5 horas atrás, Leivio Fontenele disse:

Isso mesmo @LUIZTEC... A3 é bem mais lento devido a necessidade de acesso a hardware externo para ter acesso a chave privada. o qual não ocorre com A1 haja vista que o mesmo já tem a chave privada quando exportada ao arquivo.

A3 oferece maior segurança...mais perde em performance. 

 

6 horas atrás, LUIZTEC disse:

A assinatura do A1 e A3 estão funcionando perfeitamente. A minha dúvida é que a assinatura do A3 é muito mais lenta que do A1. Estou assinando 80 eventos, no A1 leva segundos para fazer, já no A3 leva mais de 5 minutos.  Isso é normal, já que a assinatura do A3 é feita pelo pendrive?

 

Leivio, essa opção do CertFly também tem a dependência do C#?

Não funciona sem a versão necessária do C# instalada, e apresenta incompatibilidade com o Windows XP?

Eu fiz testes com o Polictryp que alguém disponibilizou aqui no fórum também, e funcionou perfeito com A1 e A3 também...

Mas isso só internamente aqui na empresa, ainda não disponibilizamos para nenhum cliente, estamos aguardando uma posição oficial em relação a assinatura com o A3...se vai haver solução que não dependa do C# e de S.O

Postado (editado)

Se ao dizerem que depende do C# é depender do .NET Framework instalado, então sim!
Precisa da versão 4.0 instalada, que é a última compatível com o Windows XP e que vêm já no Service Pack 3.
O Windows Seven, se não me engano vêm com o .NET 3.5, o que fará depender da instalação do 4.0.

Isso com a eSocialSignature.dll, juntamente da Security.Cryptografy.dll.

Já a CertFly pelo o vi esta usando o .NET 4.6.1.

Mas o pessoal da ACBr com certeza deve liberar uma solução para isso.
Com Lazarus é possível.
Aguardemos...

Editado por tiago.prs
Postado (editado)
7 minutos atrás, tiago.prs disse:

Se ao dizerem que depende do C# é depender do .NET Framework instalado, então sim!
Precisa da versão 4.0 instalada, que é a última compatível com o Windows XP e que vêm já no Service Pack 3.
O Windows Seven, se não me engano vêm com o .NET 3.5, o que fará depender da instalação do 4.0.

Isso com a eSocialSignature.dll, juntamente da Security.Cryptografy.dll.

Já a CertFly pelo o que esta usando o .NET 4.6.1.

Mas o pessoal da ACBr com certeza deve liberar uma solução para isso.
Com Lazarus é possível.
Aguardemos...

Isso, eu estava me referindo ao .NET sim... foi mal!

Certo, então independente de S.O a dependência sera do .NET 4.0 nesse caso, certo?

Que no caso do XP, só atualizando para o SP3.

Essa eSocialSignature.dll e Security.Cryptografy.dll estão versionadas em algum lugar? (Encontrei aqui, ta com o link para o github)

Sabe me dizer se essa solução é a que será adotada nos fontes do Acbr para o e-social?

Obrigado Tiago

Editado por juuninho
  • Este tópico foi criado há 2611 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...
The popup will be closed in 10 segundos...