sexta-feira, 24 de julho de 2009

Assinatura Digital EAD PAF-ECF

Ola pessoal!!!

Após algum tempo estou voltando a postar novas informações sobre um assunto muito discutido em alguns fóruns de programação. A assinatura digital EAD usada em aplicativos PAF-ECF para atender a nova legislação.

Neste post vou colocar a disposição o exemplo da função que estou usando em meu aplicativo para gerar essa assinatura EAD.

Observações:
Essa função que estou usando foi adquirida em um fórum disponibilizada por um membro e adaptada em meu aplicativo. Todo credito pelo desenvolvimento deve ser atribuído ao mesmo.

Essa assinatura é realizada apenas usando a DLL Libeay32.dll e a unit Libeay32.pas.




Vamos lá:

O primeiro passo é fazer o download da DLL e da Unit necessários para o funcionamento da função em questão.

Clique nos links a seguir para efetuar tal download:

http://www.disi.unige.it/person/FerranteM/delphiopenssl/libeay32.pas

http://www.dll-files.com/dllindex/dll-files.shtml?libeay32

Depois adcione a unit Libeay32.pas ao seu projeto.

Copie os códigos abaixo e faça as adaptações necessárias no seu projeto.

// função para gerar a assinatura EAD
function TECF.AssinaArquivo(fArquivo: String): Boolean;
var aAssinatura : String;
strList : TStringList;
begin
aAssinatura := Sign_RSA_MD5(ExtractFilePath(Application.ExeName)+'avisnet.pem',fArquivo);
// Assina Arquivo
strList := TStringList.Create;
strList.LoadFromFile(fArquivo);
strList.SaveToFile(fArquivo);
// strList.Add('EAD10'+copy(aAssinatura,1,254));
strList.Add('EAD'+aAssinatura);
strList.SaveToFile(fArquivo);
strList.Free;

end;



// função que retorna a assinatura digital EAD usando a DLL
function TECF.Sign_RSA_MD5(chave_privada, arquivo_assinar: string): string;
var Len: cardinal;
mdctx: EVP_MD_CTX;
inbuf, outbuf: array [0..1023] of char;
key: pEVP_PKEY;
a : pEVP_PKEY;
keyfile: pBIO;
oArquivo : TStringList;
begin
if FileExists(chave_privada) = false then
begin
raise Exception.Create('Arquivo da chave privada não foi encontrado.');
end;
if FileExists(arquivo_assinar) = false then
begin
raise Exception.Create('Arquivo para ser assinado não foi encontrado.');
end;
a := nil;
OpenSSL_add_all_algorithms; //
OpenSSL_add_all_ciphers; // InitOpenSSL
OpenSSL_add_all_digests; //
ERR_load_crypto_strings; //
try
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(chave_privada));
key := PEM_read_bio_PrivateKey(keyfile, a, nil, nil);
if key = nil then
begin
raise Exception.Create('Não foi possível ler a chave privada.');
end;
oArquivo := TStringList.Create;
oArquivo.LoadFromFile(arquivo_assinar);
// StrPCopy(inbuf,oArquivo.Text);
// oArquivo.Free;
EVP_SignInit(@mdctx, EVP_md5());
EVP_SignUpdate(@mdctx, pChar(oArquivo.Text), StrLen(pchar(oArquivo.Text)));
// EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
EVP_SignFinal(@mdctx, @outbuf, Len, key);
BinToHex(outbuf, inbuf,Len);
inbuf[2*Len]:=#0;
oArquivo.Free;
Result := inbuf;
finally
EVP_cleanup; // FreeOpenSSL
end;

end;



Caso tenha efetuado corretamente os procedimentos esta pronto a rotina para assinar digitalmente um arquivo.

Basta agora compilar o projeto, selecionar um arquivo no formato TXT e enviar o comando para executar a rotina. Depois é só conferir a assinatura com o aplicativo eECFc.exe 3.0.12.0.

Qualque dúvida, post um comentário, terei prazer em tirar as dúvidas.

28 comentários:

  1. Já fez o teste no delphi 2009? tentei aqui e não consegui.

    ResponderExcluir
  2. Ainda não efetuei os testes com o delphi 2009, vou efetuar alguns testes aqui e volto a postar novas informações no blog.

    ResponderExcluir
  3. Efetuei os testes aqui pelo delphi 2009. A primeira que notei é que o link da DLL que passei, não se refere a versão atualizada. baixe a versão 0.9.8.6 que funcionará.
    Um outro detalhe que não mencionei, é sobre a criação da chave privada, será necessário criar a mesma e capturar o modulo para criação do arquivo de verificação XML. no link http://www.activedelphi.com.br/forum/viewtopic.php?t=47420&sid=8968512830dac224fe0d22d809c5d086 voce encontrará informações sobre como criar essa chave.
    Valeu!!!

    ResponderExcluir
  4. Não funciona no Delphi 2009, vc pode clocar um exemplo??

    ResponderExcluir
  5. Resolvi efetuar os testes detalhados aqui e realmente a DLL não funciona corretamente com o Delphi 2009. O retorno da função "BIO_ctrl" retorna como nula ao efetuar a leitura da chave privada. Quando efetuei os testes anteriores, apenas complilei o aplicativo, e até deu a mensagem mas como não estava usando uma chave privada válida, avaliei que o problema estava na chave. Ainda estou efetuando algumas pesquisas para ver se consigo achar uma solução para o problema. Qualquer novidade adiciono a informação aqui no blog. Grato!!!

    ResponderExcluir
  6. Luis Preciso de uma ajuda ...
    Cara nao to conseguindo de maneira nenhuma gerar essa EAD ...
    Alias ate consigo gerar, mas o validador diz que a chave não é válida... Estou precisando muito disso.. Será que você poderia me prestar um consultoria? Minha empresa ate pagaria por esse serviço... Só falta isso para marcarmos nossa homologação.. Se puder me ajudar, desde já agradeço.

    Email. suporte@climaq.com.br

    ResponderExcluir
  7. Me informe qual Plataforma de programação e o metodo que esta usando para gerar a assinatura EAD. Neste exemplo uso o Delphi 7 com a DLL libeay32 que já sabemos não funcionar com o Delphi 2009. Obrigado!!!

    ResponderExcluir
  8. Luis Obrigado pela sua resposta...
    Eu uso Delphi 7 e ja tentei usar varias Dlls..
    Tentei tambem com a Libeay32, usando essa função que você postou... Porem, no XML do Programa validador é necessário informar o Modulo que no caso seria a chave publica e o expoente ... Então nao deu muito certo.. Ja te add no msn.

    Desde ja agradeço.

    ResponderExcluir
  9. Bom dia Luis, tudo bem ?

    Utilizei seu exemplo para criar o registro EAD na minha aplicação (plataforma: Delphi 7.0 com libeay32.dll, versão 0.9.8.6), em testes aqui na empresa funcionou perfeitamente, porém em alguns clientes está ocorrendo o seguinte erro ao iniciar o aplicativo: "Aplicativo não inicializado corretamente (0xc0150002). Clique em 'OK' para finalizar a execução".
    Verificando descobri que o problema é ao carregar a libeay32.dll.
    Já passou por algo parecido ? Tem alguma sugestão ?

    Desde já agradeço!!

    ResponderExcluir
  10. Tive este problema e descobri que o problema estava na versão da DLL que estava enviando para o cliente. A versão que funciona é a 0.9.8.6 e junto com o executável enviei uma versão anterior. Verifique a versão que esta no cliente.

    ResponderExcluir
  11. Já verifiquei a versão é a mesma. Fiz um teste agora instalando uma máquina virtual com Windows XP SP2, instalei apenas o windows e o meu aplicativo, o erro ocorreu. Na minha máquina de trabalho onde tem o Delphi, servidor de banco de dados instalado, etc, o erro não ocorre. Sabe existe mais alguma arquivo ou programa necessário para que funcione ?

    Obrigado!

    ResponderExcluir
  12. Um usuário de um forum do site ActiveDelphi disse que atualizando o .Net Framework para a 3.5, resolveu o problema. Numca reparei se meus clientes que usam o aplicativo tem esta versão do .Net Framework. Mas em todos está funcionando a aplicação.

    ResponderExcluir
  13. Olá Luis, ví seus artigos no site da Devmedia referênte a assinatura digital e achei bem interessantes. Gostaria de saber se já alguma pesquisa atual referênte a assinatura digital utilizando o Rad Studio 2009 ou 2010.

    David

    ResponderExcluir
  14. Olá David! Pelo que tenho visto de comentários, a solução esta sendo usar as DLL's dos fabricantes. Recentemente tive em contato com uma empresa que usou a DLL sigman fornecida pela Daruma. Abs!

    ResponderExcluir
  15. Luis boa tarde, estou desenvolvendo um PAF-ECF, utilizando as dlls e o emulador da Bematech, porém ainda não consegui fazer com o que o resultado da Impressora fiscal (Emulador) saia tambem no vídeo, se você puder meu ajudar obrigado.
    Att.

    Wladmir Ribeiro - RJ

    ResponderExcluir
  16. Olá Wladmir!

    O ideail para o funcionamento do emulador da bematech, e através de cabo serial ligando um micro ao outro. Para uso na mesma máquina alguns comandos não irão funcionar perfeitamente.
    Para o funcionamento do emulador no mesmo micro, você deverá alterar a chave "EMULMFD" do arquivo bemafi32.ini de 0 para 1. Devo ainda salientar que o uso emulador no mesmo micro sobrecarrega muito a memoria e poderá carretar na não exibição dos dados no display.

    Abs!

    ResponderExcluir
  17. Luis, antes de qualquer coisa, muito obrigado pela atenção, porém eu não fui claro na minha pergunta, eu já estou utilizando o emulador, consigo realizar todas as operações sem problemas. O que eu estou querendo é exibir as mesmas informações que estão saindo no emulador no vídeo, ou seja, sai no emulador e também no vídeo. conforme já observei em vários PDVs. Mais uma vez, muito obrigado.

    Abs.
    Wladmir.

    ResponderExcluir
  18. Não sei se entendi ainda sua pergunta, mas acredito que o video que você esta se referindo, é a tela de seu aplicativo.
    Se for, acredito que você esteja gravando as informações do cupom emitido em banco de dados, sendo assim, adicione em sua tela um componente TMemo e crie uma rotina para adicionar dados no mesmo, formatando-os conforme sua preferencia, e ao enviar as informações para a impressora emitir o cupom, envie também para este memo.

    Abs!

    ResponderExcluir
  19. Muito obriado Luis, é exatamente isso que preciso fazer, eu já havia pensado TMemo, mas acreditei que teria alguma coisa pronta.

    Mais uma vez, muito Obrigado.

    Wladmir.

    ResponderExcluir
  20. Luis, como gero o arquivo .pem?
    Desde já agradeço.

    ResponderExcluir
  21. Olá!
    Você precisará de baixar o OpenSSL. Neste link abaixo tem todas as informações necessárias.

    http://www.forumweb.com.br/foruns/index.php?/topic/79108-paf-ecf-como-gerar-chave-publica-e-privada/

    Abs!

    ResponderExcluir
  22. Luis, gostei muito deste blog - tem me ajudado muito.
    Gostaria de esclarecer uma dúvida - uma confirmação, na verdade. O Menu fiscal são somente essas opções que você colocou no artigo?
    Digo isto porque o software que estou cuidando não atende a restaurantes e estou pensando em tirar as opções Transf. Mesas e Mesas Abertas e colocar no lugar Vendas do Período e Tab. Índice Técnico Produção - tá correto?

    ResponderExcluir
  23. Ola!
    Este material foi feito com as opções basicas e são referentes ao roteiro 1.03. Ja estamos no roteiro 1.05 partindo para o 1.06.
    Acesse o link http://www.devmedia.com.br/luisgodinho, lá tem mais algumas informações sobre o assunto.
    Abs!

    ResponderExcluir
  24. Luis, vc conseguiu resolver o problema da assinatura EAD com o delphi 2009 ou 2010?

    Alex Maia
    tapajosc@msn.com

    ResponderExcluir
  25. Pelo que sei não foi possível assinar com o Libeay32 usando o delphi 2009. A solução que algumas pessoas que tenho contato encontrou foi usar a DLL Sigma da daruma, ou as DLL dos fabricantes.
    Abs!

    ResponderExcluir
  26. Boas,

    Resolvi o problema do Delphi 2009 com :

    BIO_read_filename(keyfile, PAnsiChar(UTF8Encode(chave_privada)));

    em vez de

    BIO_read_filename(keyfile, PChar(chave_privada));

    Assim já não dá erro e funciona bem.

    ResponderExcluir
  27. Boa tarde! gostaria de saber como gerar a chave publica e a Privada p/ a Elgin, na Bematech/sweda/etc... existe uma função, mais na Elgin, não encontrei, e nem o suporte deles conseguiram me passar essa informação...

    Saudações!

    ResponderExcluir
  28. A chave não esta vinculada a impressora e sim ao aplicativo. pode usar a da bematech uma unica vez e usar na aplicação atendendo a qualquer impressora que esteja em uso. Veja o link:

    http://partners.bematech.com.br/2009/06/edicao-128-nova-dll-para-assinatura-digital-registro-ead/

    Abs.!

    ResponderExcluir