|
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
flavioexata Novato
Registrado: Terça-Feira, 29 de Janeiro de 2008 Mensagens: 1
|
Enviada: Seg Abr 20, 2009 4:13 pm Assunto: Registro EAD no PAF-ECF |
|
|
Colegas,
estamos em processo de homologação e estamos agarrados na geração do registro EAD dos arquivos do PAF-ECF.
Agora os homologadores estão de posse de um aplicativo eECFc.exe que valida se a assinatura digital bate com a chave pública. Então nós fomos premiados como os primeiros a serem validados com este aplicativo aquí no estado.
Não precisa nem mensionar que o código não bateu com a chave pública.
Pois bem, estamos utilizando o componente tplockbox207 para gerar o RSA do registro EAD e parece realmente que está tudo OK.
Geramos uma chave pública e uma privada pelo ExRSAKey.exe que vem com o tplockbox, geramos o MD5 e geramos o EAD com o código abaixo:
function AssinaturaDigital(Caminho:String) : String;
var
EAD: string;
RSA: TLbRSASSA;
MD5 : String;
begin
MD5 := Alinha_String( 'E', ' ', 256, '10' + MD5Print(MD5File(Caminho)) );//Gero o md5 começando com 10 alinhado à esquerda em 256 Caracteres.
RSA := TLbRSASSA.Create(Application);
RSA.HashMethod := hmMD5;
RSA.KeySize := aks1024;
RSA.PrivateKey.ExponentAsString := 'AQUÍ FICA O MEU EXPONENTE PRIVADO';
RSA.PrivateKey.ModulusAsString := 'AQUÍ FICA MEU MODULO PRIVADO';
RSA.SignString(MD5);
Result := RSA.Signature.IntStr;
RSA.Free;
end;
Se alguém tiver alguma idéia de como resolver este problema ou se alguém quiser uma cópia do eECFc.exe para testar, é só me avisar.
Valeu. |
|
Voltar ao Topo |
|
|
serverinformatica Novato
Registrado: Quarta-Feira, 29 de Abril de 2009 Mensagens: 1
|
Enviada: Qua Abr 29, 2009 10:11 am Assunto: paf-ecf |
|
|
ola, amigo desculpe estar perguntando em vez de responder, mas como esse topico ja é mais antigo, imagino que vc ja deva ter conseguido uma solução. vc ja conseguiu validar a assinatura do paf ?
Obrigado. |
|
Voltar ao Topo |
|
|
gustavocco Administrador
Registrado: Sexta-Feira, 6 de Fevereiro de 2004 Mensagens: 4253 Localização: Chapecó - SC
|
Enviada: Qui Mai 14, 2009 10:58 am Assunto: |
|
|
Olá, bom dia. Consegui validar o arquivo utilizando esse procedimento que vi num outro fórum:
Código: |
eu estou usando o OpenSSL para assinar meus arquivos e estou conseguindo validá-lo no eECFc v3.12 de 06/02/2009.
O único problema que enfrentei foi conseguir configurar o XML corretamente. Com relação à assinatura em si, não precisei mexer em nada. Fiz exatamente como está sendo explicado em um tópico aqui do fórum, mais precisamente pelo Daniel Simões. Só não localizei o link aqui, mas posto os comandos básicos abaixo.
=>Como obter uma chave privada:
openssl genrsa -out chave.pem 1024
Onde:
Chave.pem = arquivo onde a chave privada será gravada. Somente executar uma vez.
=> Como obter a assinatura digital de um arquivo
Comando: openssl dgst -md5 -sign chave.pem -out ead.txt -hex arquivo.txt
Onde:
Chave.pem = arquivo com a chave privada gerada anteriormente
arquivo.txt = arquivo a ser assinado. O arquivo não será modificado. A assinatura retornará no arquivo ead.txt.
ead.txt = arquivo onde será retornada a assinatura digital gerada.
Você deverá pegar o conteúdo do arquivo ead.txt, excluir desta informação o nome do arquivo assinado, e concatenar com a string EAD e colocar dentro do arquivo assinado.
=>Como obter o módulo da chave privada (necessário para montar o XML do eECFc)
Comando: openssl rsa -in chave.pem -modulus -out modulo.txt
Onde:
Chave.pem = arquivo com a chave privada gerada anteriormente.
modulo.txt = Arquivo onde será gravado o módulo. No arquivo conterá o módulo e a chave privada. Você pega o módulo e cola dentro do arquivo XML no campo específico. O expoente eu não precisei alterar..
=> Estrutura XML para fazer a validação da assinatura pelo programa eECFc.exe
Nome do arquivo: Empresa Desenvolvedora.XML. Deve ser o mesmo nome que estiver constando na TAG <nome> do arquivo.
<xml>
<empresa_desenvolvedora>
<nome>Empresa Desenvolvedora</nome>
<chave
<modulo>9A99A052DA9AB6186474ABECD3E64371359FC23CA346C1958429F8C7081DCF17C92333C78EA20
4E634089F3798189DA6F42FAB6D6A5ED24215C6417F8B756EB7662383DCDBAC9316EBF6472427BA8
5
E361AA25282526E4D2D31CABCA6357ECF5DB074BE0BF7B7DC51D2519D29D74B43A47B1498B23274C
A
E777F9BF8921E9AD7</modulo>
<expoente_publico>00000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0
00000000000010001</expoente_publico>
</chave>
</empresa_desenvolvedora>
Postem os resultados.
Augusto - Microsia
|
Baixei o OpenSSL em: http://www.slproweb.com/products/Win32OpenSSL.html
meu arquivo XML ficou:
Código: |
<xml>
<empresa_desenvolvedora>
<nome>Top System Informatica Ltda</nome>
<chave>
<modulo>D137D25B3FD69F3167926BC764E46622FF890F079E71511A624C6585EFA5FFC1003EC3883C13DE0FC7B46F213F3300872A5717C912FFD76A96E10693E08F48825F28E7C70D4E8268389714B70B431EFD944FC3057C4E015BCFD1021F7ABD39B281E52F6F0FF91C7CF89D77C7565BD09D70BAE7FE1D3F558121D6CF0803F480F3</modulo>
<expoente_publico>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001</expoente_publico>
</chave>
</empresa_desenvolvedora>
|
Pelo aplicativo eECFc Consegui validar corretamente.
Att. Gustavo. _________________ Top System - www.topsystem.com.br |
|
Voltar ao Topo |
|
|
Alexandro.sds Novato
Registrado: Quinta-Feira, 28 de Mai de 2009 Mensagens: 2 Localização: Araguaína-TO
|
Enviada: Qui Mai 28, 2009 12:05 pm Assunto: Re: Registro EAD no PAF-ECF |
|
|
flavioexata escreveu: | Colegas,
estamos em processo de homologação e estamos agarrados na geração do registro EAD dos arquivos do PAF-ECF.
Agora os homologadores estão de posse de um aplicativo eECFc.exe que valida se a assinatura digital bate com a chave pública. Então nós fomos premiados como os primeiros a serem validados com este aplicativo aquí no estado.
Não precisa nem mensionar que o código não bateu com a chave pública.
Pois bem, estamos utilizando o componente tplockbox207 para gerar o RSA do registro EAD e parece realmente que está tudo OK.
Geramos uma chave pública e uma privada pelo ExRSAKey.exe que vem com o tplockbox, geramos o MD5 e geramos o EAD com o código abaixo:
function AssinaturaDigital(Caminho:String) : String;
var
EAD: string;
RSA: TLbRSASSA;
MD5 : String;
begin
MD5 := Alinha_String( 'E', ' ', 256, '10' + MD5Print(MD5File(Caminho)) );//Gero o md5 começando com 10 alinhado à esquerda em 256 Caracteres.
RSA := TLbRSASSA.Create(Application);
RSA.HashMethod := hmMD5;
RSA.KeySize := aks1024;
RSA.PrivateKey.ExponentAsString := 'AQUÍ FICA O MEU EXPONENTE PRIVADO';
RSA.PrivateKey.ModulusAsString := 'AQUÍ FICA MEU MODULO PRIVADO';
RSA.SignString(MD5);
Result := RSA.Signature.IntStr;
RSA.Free;
end;
Se alguém tiver alguma idéia de como resolver este problema ou se alguém quiser uma cópia do eECFc.exe para testar, é só me avisar.
Valeu. |
Bom dia!
Por gentileza me informe onde baixo o eECFc.exe
Muito obrigado! _________________ Alexandro Sousa
alexandroto@bol.com.br |
|
Voltar ao Topo |
|
|
WisneyCardeal Novato
Registrado: Quarta-Feira, 11 de Janeiro de 2006 Mensagens: 1 Localização: Uberlândia - MG
|
Enviada: Sex Mai 29, 2009 10:00 pm Assunto: Solução para EAD |
|
|
Pessoal acho que já está tudo resolvido né...
Para gerar o pem da chave usei a dica do Alexandre (Exati) no tópico
http://www.forumweb.com.br/foruns/index.ph...75707&st=20
////////////////////////////////////////////////////////////////////////////////
(Alexandre (Exati) @ May 14 2009, 11:55 AM)
Gustavo, para criar as chaves siga os procedimentos já descritos nos topicos anteriores:
Para gerar a chave Privada de 1024 bytes:
openssl genrsa -out priv_key.pem 1024
Para gerar a chave Publica a partir da privada:
openssl rsa -in priv_key.pem -pubout -out pub_key.pem
Para extrair/visualizar o expoente e o modulo:
openssl rsa -modulus -in priv_key.pem -inform PEM -text
////////////////////////////////////////////////////////////////////////////////
Para extrair o expoente e o modulo:
openssl rsa -modulus -in priv_key.pem -inform PEM -text -pubout -out modulus.pem
Obrigado Alexandre (Exati)
E para assinar os arquivos segui a dica do Anizair no tópico
http://www.forumweb.com.br/foruns/index.ph...6285&st=140
////////////////////////////////////////////////////////////////////////////////
(Anizair @ May 28 2009, 12:16 PM)
Vamos fazer o seguinte vou enviar colocar o meu programa de teste no seguinte endereço
http://code.google.com/p/infojob/downloads/list
e ai você baixa este programa e faça um teste com seu arquivo, vou colocar os fontes também.
////////////////////////////////////////////////////////////////////////////////
Aí pessoal este programa teste do Anizair usando o OpenSSL foi a solução dos problemas...
não precisa instalar o OpenSSL,
basta copiar os arquivos dll LIBEAY32.DLL e LIBSSL32.DLL pro diretório de seu executável
e adicionar ao seu projeto as units LIBEAY32.PAS e MD5.PAS
Ai segue o exemplo do programa teste do Anizair que vai ser só alegria...
Valeu, Muito Bom Anizair.... _________________ --
Att.
Wisney Cardeal
wisney@supremacia.com.br
Analista Programador
Suprema Informática LTDA. - Uberlândia- MG. |
|
Voltar ao Topo |
|
|
andrejjw Novato
Registrado: Segunda-Feira, 8 de Junho de 2009 Mensagens: 7
|
Enviada: Seg Jun 08, 2009 10:35 am Assunto: Re: Solução para EAD |
|
|
WisneyCardeal escreveu: | Pessoal acho que já está tudo resolvido né...
Para gerar o pem da chave usei a dica do Alexandre (Exati) no tópico
http://www.forumweb.com.br/foruns/index.ph...75707&st=20
////////////////////////////////////////////////////////////////////////////////
(Alexandre (Exati) @ May 14 2009, 11:55 AM)
Gustavo, para criar as chaves siga os procedimentos já descritos nos topicos anteriores:
Para gerar a chave Privada de 1024 bytes:
openssl genrsa -out priv_key.pem 1024
Para gerar a chave Publica a partir da privada:
openssl rsa -in priv_key.pem -pubout -out pub_key.pem
Para extrair/visualizar o expoente e o modulo:
openssl rsa -modulus -in priv_key.pem -inform PEM -text
////////////////////////////////////////////////////////////////////////////////
Para extrair o expoente e o modulo:
openssl rsa -modulus -in priv_key.pem -inform PEM -text -pubout -out modulus.pem
Obrigado Alexandre (Exati)
E para assinar os arquivos segui a dica do Anizair no tópico
http://www.forumweb.com.br/foruns/index.ph...6285&st=140
////////////////////////////////////////////////////////////////////////////////
(Anizair @ May 28 2009, 12:16 PM)
Vamos fazer o seguinte vou enviar colocar o meu programa de teste no seguinte endereço
http://code.google.com/p/infojob/downloads/list
e ai você baixa este programa e faça um teste com seu arquivo, vou colocar os fontes também.
////////////////////////////////////////////////////////////////////////////////
Aí pessoal este programa teste do Anizair usando o OpenSSL foi a solução dos problemas...
não precisa instalar o OpenSSL,
basta copiar os arquivos dll LIBEAY32.DLL e LIBSSL32.DLL pro diretório de seu executável
e adicionar ao seu projeto as units LIBEAY32.PAS e MD5.PAS
Ai segue o exemplo do programa teste do Anizair que vai ser só alegria...
Valeu, Muito Bom Anizair.... |
Como eu obtenho o módulo e o expoente publico desses arquivos gerados a fim de configurar o arquivo xml ? |
|
Voltar ao Topo |
|
|
ZeroDrop Novato
Registrado: Sexta-Feira, 15 de Janeiro de 2010 Mensagens: 6
|
Enviada: Sáb Fev 13, 2010 9:03 am Assunto: |
|
|
Houston, we have a problem!!!!
Tem um detalhe... Realmente, esta rotina funciona beleza, lendo o arquivo PEM e carregando a chave.
No entanto, na legislação do PAF-ECF, diz que a chave tem que ser de conhecimento exclusivo da empresa desenvolvedora. E eu concordo, pois desta maneira eu evito que uma outra empresa autentique um arquivo em nome da minha empresa. Logo, eu usando um arquivo PEM, se em algum dos meus clientes o arquivo PEM for substituído por outro (gerar um arquivo pem não é difícil), o meu sistema continuará assinando direitinho os arquivos gerados, mas se bater uma fiscalização, não vai fechar com a chave de minha empresa, e todos os arquivos gerados pelo meu sistema serão considerados inválidos. Se um concorrente desleal quiser me prejudicar e tiver acesso ao micro do meu cliente, torna-se muito fácil.
Par atender 100% da legislação e ficar tranquílo quanto á confiabilidade da minha assinatura, um método diferente de assinar é necessário, e acredito que os colegas deveriam implementar esse método também: é inserir a chave criptográfica dentro do código-fonte e atribuí-lo á uma variável String, pública, de modo que a chave possa ser acessada de qualquer parte do programa.
Desta maneira a chave torna-se de conhecimento exclusivo da empresa (a chave que encontra-se no XML só será fornecida á Receita exclusivamente, e somente em caso de vistoria, então ninguém mais a possuirá) e o cliente usuário do meu sistema não terá como danificar o arquivo PEM ou substituí-lo.
Só que estou com problemas para implementar isso. Utilizando o esquema acima, ele carrega a chave para um registrador BIO a partir de um arquivo, e está difícil para fazer ele carregar a chave para o BIO á partir de uma variável de memória.
Tudo está na procedure ReadPrivateKey que consta no exemplo "teste" do Anizair, citado neste post. O original é o seguinte:
Código: |
Function TMainForm.ReadPrivateKey(AFileName: TFileName): pEVP_PKEY;
var
keyfile : pBIO;
a : pEVP_PKEY; //Because PEM_read_bio_PrivateKey uses parameters by-reference
begin
a := Nil;
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(AFilename));
result := PEM_read_bio_PrivateKey(keyfile, a, nil, self);
BIO_free(keyfile);
if result = nil then
raise Exception.Create('Impossível ler a chave privada. ' + getErrorMessage);
end;
|
O que eu tentei foi o seguinte:
Código: |
Function TMainForm.ReadPrivateKey(AFileName: TFileName): pEVP_PKEY;
var
keyfile : pBIO;
a : pEVP_PKEY; //Because PEM_read_bio_PrivateKey uses parameters by-reference
begin
a := Nil;
keyfile := BIO_new(BIO_s_mem());
BIO_puts(keyfile, PChar(ChaveMD5Valor));
result := PEM_read_bio_PrivateKey(keyfile, a, nil, nil);
BIO_free(keyfile);
if result = nil then
raise Exception.Create('Impossível ler a chave privada. ' + GetErrorMessage);
end;
|
Eu troquei o tipo de registro BIO, de BIO_s_file para BIO_s_mem, e joguei o conteúdo da variável ChaveMD5Valor (que contém o exato mesmo conteúdo do arquivo PEM) para dentro deste BIO. Até aí já comprovei que funcionou certinho.
O problema está na PEM_read_bio_PrivateKey. Ela não consegue extrair de dentro do registro BIO a chave e atribuí-la ao "result" da função. Dá o mesmo erro que dá se o arquivo PEM estiver vazio: "PEM_read_bio:no start line"
Se alguém tiver mais conhecimento de libeay32 e puder dar uma luz, a gente agradece!
Falou! |
|
Voltar ao Topo |
|
|
daytron Novato
Registrado: Quinta-Feira, 15 de Janeiro de 2009 Mensagens: 10
|
Enviada: Qua Fev 17, 2010 8:12 am Assunto: |
|
|
Aqui estou utilizando uma dll da bematech pra gerar o EAD, chamada sign_bema.dll. Acredito que essa dll utilize a libeay32 para gerar essa chave.
No site da bematech tem para baixar. Ela vem junto com o arquivo da bemafi32.dll.
Da uma olhada, as vezes...
[]'s |
|
Voltar ao Topo |
|
|
ZeroDrop Novato
Registrado: Sexta-Feira, 15 de Janeiro de 2010 Mensagens: 6
|
Enviada: Qua Fev 17, 2010 9:09 am Assunto: |
|
|
daytron escreveu: | Aqui estou utilizando uma dll da bematech pra gerar o EAD, chamada sign_bema.dll. Acredito que essa dll utilize a libeay32 para gerar essa chave.
No site da bematech tem para baixar. Ela vem junto com o arquivo da bemafi32.dll.
Da uma olhada, as vezes...
|
Opa!
Essa DLL da Bematech carrega a chave MD5 de um arquivo PEM externo? Se sim, então seria o mesmo caso deste artigo. Mas se ela receber a chave através de um parâmetro, aí sim poderia me resolver.
Eu preciso de uma maneira de assinar SEM precisar de um arquivo PEM externo, de modo a conseguir armazenar minha chave MD5 diretamente nas linhas do código-fonte e atribuir esta chave á uma variável, que será utilizada para assinar, tornando o processo de assinatura imune á intervenção do usuário. Já consegui resolver 80% do problema, acredito.
Valeu! |
|
Voltar ao Topo |
|
|
daytron Novato
Registrado: Quinta-Feira, 15 de Janeiro de 2009 Mensagens: 10
|
Enviada: Qua Fev 17, 2010 9:48 am Assunto: |
|
|
ZeroDrop escreveu: | Opa!
Essa DLL da Bematech carrega a chave MD5 de um arquivo PEM externo? Se sim, então seria o mesmo caso deste artigo. Mas se ela receber a chave através de um parâmetro, aí sim poderia me resolver.
Eu preciso de uma maneira de assinar SEM precisar de um arquivo PEM externo, de modo a conseguir armazenar minha chave MD5 diretamente nas linhas do código-fonte e atribuir esta chave á uma variável, que será utilizada para assinar, tornando o processo de assinatura imune á intervenção do usuário. Já consegui resolver 80% do problema, acredito.
Valeu! |
Acredito que seja como voce precise. Eu utilizado as chaves publicas e privadas direto no código tambem.
Está ai a declaração da função que eu uso:
Código: |
function generateEAD(NomeArq: String; ChavePublica: String; ChavePrivada: String; EAD:String; Sign: Integer): integer; stdcall; external 'sign_bema.dll'; |
|
|
Voltar ao Topo |
|
|
ZeroDrop Novato
Registrado: Sexta-Feira, 15 de Janeiro de 2010 Mensagens: 6
|
Enviada: Ter Jul 13, 2010 5:25 pm Assunto: |
|
|
Já consegui resolver.
O OpenSSL gera o arquivo PEM com um #10 depois de cada linha, que é o caractere de quebra de linha, e é invisível. Minha variável não possuía estes caracteres. No Windows, a quebra de linha é #13 + #10, mas no Linux é só #10. Logo, o windows não mostra as quebras da chave e dá a impressão que elas não existem.
Daí, a declaração da minha variável ficou assim:
Código: | ChaveMD5ValorPriv := '-----BEGIN RSA PRIVATE KEY-----' + #10 +
'MIICXQIBAAKBgQDXjAe9ltrY+sdcRNkshk+wVJN2lrcsdmO4oMyaSTzN/NgGyEaA' + #10 +
'KVwWKROU7oXKt9YlXyXMFbhZUJ0AAAiHecWGq0ugisHuowgGKuYmhRiBHGWpgsF9' + #10 +
'nG9EwNqEEBpgYnsmpXrGytAYck1R4eBg+ZIqRYM5M6h+dV7FaixJrcg5VwIDAQAB' + #10 +
(...)
'WjPtPhdxnDpYoMlqPORGyZI+BttxHoI9cGlZ7ZXureSxHrJ67UcUydrVc5HIXb3k' + #10 +
'BQVcxqCKFvw/0EexQzsCQQCbk2g+/yrr/I38tQcQI7fgSmHJ1AziEBC/SK+MV7mG' + #10 +
'5TqpIGVsHgufKXyTmyb4fHnBdBRG0tEX/Hogie75nHPO' + #10 +
'-----END RSA PRIVATE KEY-----' + #10;
|
Na verdade a declaração é maior, usei o "(...)" para garantir a confidencialidade da minha chave.
Daí retirei o arquivo como parâmetro da minha função, e ela ficou assim:
Código: | Function ReadPrivateKey : pEVP_PKEY;
var
keyfile : pBIO;
NomeArq : TFileName;
a, TempKey : pEVP_PKEY;
ArquivoSaida : TextFile;
begin
a := Nil;
keyfile := BIO_new(BIO_s_mem());
BIO_puts(keyfile, PAnsiChar(ChaveMD5ValorPriv));
TempKey := PEM_read_bio_PrivateKey(keyfile, a, nil, nil);
BIO_free(keyfile);
if TempKey = nil then
raise Exception.Create('Impossível ler a chave privada. ' + GetErrorMessage)
else
ReadPrivateKey := TempKey;
end;
|
Dessa maneira, o arquivo PEM pode ser inserido no código-fonte e dispensa a existência de um arquivo externo para que seja feita a assinatura do arquivo gerado, garantindo a confidencialidade de minha chave, que passa á ser embutida no EXE da aplicação.
Então, se alguém quiser implementar desta forma, está aqui a dica!
Até mais! |
|
Voltar ao Topo |
|
|
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|