Nota Fiscal Eletrônica - Certificado Digital

Eu estou iniciando o desenvolvimento do módulo de nota fiscal eletrônica mas nunca
integrei o Java (ou nenhuma outra linguagem) à certificados digitais.

Alguém tem algum exemplo de como integrar isso ao Java para colocar
a chave no XML de envio da NFe?

Muito obrigado.

Ola Marcio !

O uso de certificados digitais na NF-e é constante.
Para vc consumir um web service, e assinar uma nota(xml). E esse processo é o mais usado em toda a NFe.

Para consumir os WS endico vc comecar a ler primeiro:

  • Manual de integração - disponivel no www.nfe.fazenda.gov.br
  • Tutorias de Axis(por exmplo) para consumo dos WS

Os certificados não são tão criticos assim.

[ ]s,

Muito bom dia, Mateus!

Sobre o consumo de WebServices, sem problemas.

Minha principal dúvida é como vou colocar os dados do certificado digital
dentro do XML (coleta dos dados).

Inté.

Também estou pesquisando sobre o assunto. Achei essa apostila muito útil: http://www.javapassion.com/j2ee/SecurityBasics_speakernoted.pdf

Alguem conhece alguma empresa ou alguem em Belo Horizonte que implante o processo de NFe em java?

Pessoal, a quem interessar, achei esse site:

http://nf-eletronica.com/

Ele tem exemplos sobre como realizar assinaturas e algumas integrações.
Pode fazer vc ganhar algum tempo.

Só não achei nada referente ao Java, mas não custa nada olhar.

Inté.

Um link interessante http://www.jugms.com.br/javaneiros2008/palestras/NF-e.pdf que pode te ajudar marcio
Vc já deu uma olhada nesse post http://www.guj.com.br/posts/list/83758.java ?

[quote=ramilani12]Um link interessante http://www.jugms.com.br/javaneiros2008/palestras/NF-e.pdf que pode te ajudar marcio
Vc já deu uma olhada nesse post http://www.guj.com.br/posts/list/83758.java ?[/quote]

Cara, apesar de ter feito uma pesquisa no GUJ confesso que não tinha visto este site.
Vou dar uma olhada pois prefiro fazer no Java do que no .net, já que tenho muita coisa pronta no Java, apesar da
parte da assinatura eu já ter conseguido no .net.
Muito obrigado pela dica.

Inté.

Sobre essa informação de ter um certificado para o ERP e outro para o estabelecimento emissor da NF-e. Alguém está trabalhando dessa forma confirma essa informação?
Sobre a homologação do software por estado, alguém já fez esse processo de homologação do software junto ao Sefaz, poderia contar como foi a experiência?

Abraço

Só uma outra pergunta: alguém aqui tem o exemplo para chamar o método de consulta
do status do serviço (NfeStatusServico) utilizando um certificado do tipo A3?

Inté.

Estou tendo problemas aqui

[code]package santri.nfe;

import java.security.Provider;
import java.security.Security;
import santri.nfe.ws.goias.homolog.status.*;

public class StatusNfe {

public static void rodarProcesso() throws Exception {

	String nfeCabecMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><cabecMsg xmlns=\"http://www.portalfiscal.inf.br/nfe\" versao=\"1.02\"><versaoDados>1.07</versaoDados></cabecMsg>";
	String nfeDadosMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><consStatServ xmlns=\"http://www.portalfiscal.inf.br/nfe\" versao=\"1.07\"><tpAmb>2</tpAmb><cUF>52</cUF><xServ>STATUS</xServ></consStatServ>";

	// Load the configuration file
	if (configProvider())
		System.out.printf("Library carregada com successo\n\n");
	else {
		System.out.printf("Erro ao carregar a library\n\n");
		return;
	}

	System.setProperty("javax.net.ssl.keyStore", "NONE");
	System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
	System.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-FeitianPKCS");
	System.setProperty("javax.net.ssl.keyStorePassword", "********");

	NfeStatusServico_Service service = new NfeStatusServico_Service();
	System.out.println(service.getNfeStatusServico().nfeStatusServicoNF(
			nfeCabecMsg, nfeDadosMsg));

}

public static boolean configProvider() {

	String configName = "C:\\Estudo\\Token\\pkcs11.cfg";
	try {
		Provider p = new sun.security.pkcs11.SunPKCS11(configName);
		Security.addProvider(p);
	} catch (Exception e) {
		e.printStackTrace();
		return false;
	}

	return true;
}

}[/code]

Está dando o seguinte erro:

com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(Unknown Source)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(Unknown Source)
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
at com.sun.xml.internal.ws.client.Stub.process(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(Unknown Source)
at $Proxy28.nfeStatusServicoNF(Unknown Source)
at santri.nfe.StatusNfe.rodarProcesso(StatusNfe.java:29)
at santri.nfe.Main.main(Main.java:13)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
… 15 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
… 27 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
… 33 more

Alguém sabe o que pode ser?

Depois de muita luta com o token (A3) e muita ajuda do Alencar (philler),
consegui fazer a conexão com o servidor de NFe aqui de Goiás.
Para evitar que outros programadores Java sofram como eu, vou descrever mais ou menos
os principais problemas encontrados.

:arrow: Servidor Proxy
Se vc utiliza servidor proxy não se esqueça de colocar o parâmetro
-Dhttp.proxyHost=IP_SERVIDOR_PROXY -Dhttp.proxyPort=PORTA_PROXY
Vc corre o risco de perder um tempinho aí.

:arrow: Arquivo de Configuração do Token
A dll presente no CD da Pronova (caso do meu token) estava bem menor que a instalada em
meu computador. A Dll do CD simplesmente não funcionou. A que eu estou utilizando é
bem maior. Pode ser um índicio de problema.
Ainda no arquivo, fique atento ao nr. do slot e ao nome dado (este será utilizado posteriormente).
O meu arquivo ficou assim:

[quote]name = FeitianPKCS#11
library = C:\santri\nfe\token\ngp11v211.dll
slot = 1[/quote]

:arrow: Teste do Site da Sefaz
Tente acessar o site da Sefaz pelo IE (pelo Firefox não consegui salvar o WSDL direito)
e digite a senha do token. Se acessar, quer dizer que sua assinatura está apta à utilizar
os WebServices.
Salve o XML contendo o WSDL. No caso de Goiás, o endereço é
https://homolog.sefaz.go.gov.br/nfe/services/NfeStatusServico?WSDL
Você pode exportar o certificado (arquivo .cer) dando um duplo clique
no cadeado que aparece na parte inferior do IE. Salve este .cer (opção de 64 bits)
pois poderá ser útil (no meu caso foi).

:arrow: Gerando as classes do WebService
Para quem utiliza o Java 6, existe um utilitário chamado wsimport, muito bacana, que
já gera as classes para acessar o WebService da Sefaz.
Uma das vantagens do wsimport é que não precisa enviar outros .jars pois a tecnologia
de acesso já está no java 6.
O comando rodado (no prompt) é mais ou menos assim

wsimport -keep -p santri.nfe.ws.goias.homolog.status NfeStatusServico.xml

O programa wsimport está na pasta bin do Jre.
O parâmetro -p serve para indicar o pacote onde as classes serão geradas.
O último parâmetro identificar onde está o WSDL. Eu não conseguir colocando
o caminho https://homolog.sefaz.go.gov.br/nfe/services/NfeStatusServico?WSDL e
creio que deva ser por causa da autenticação. Por isso gerei o XML e o utilizei
aqui (deu na mesma).

:arrow: KeyStore
Me disseram que não precisa utilizar arquivo para definir KeyStore no certificado
A3. Bem, eu não consegui. O que consegui foi gerando o arquivo .jks.
Lembra-se do arquivo .cer exportado a uns tópicos acima? Pois bem, vamos utilizá-lo
agora.
No prompt de comando, digitar

keytool -importcert -file nfe.cer -keystore nfe.jks

nfe.cer é o nome do arquivo .cer exportado no IE.
nfe.jks é o arquivo a ser gerado.
Esse comando irá pedir uma senha. Basta digitá-la e confirmá-la.

:arrow: No Eclipse
No fonte, para realizar a conexão segura, será necessário registrar
o provider do token. Isto pode ser feito desta maneira:

public boolean configurarProvider(){ String configName = "C:\\santri\\nfe\\token\\pkcs11.cfg"; try { Provider p = new SunPKCS11(configName); Security.addProvider(p); } catch(Exception e) { e.printStackTrace(); return false; } return true; }

O “configName” é o arquivo contendo as configurações do token.

Também é necessário definir o “alias” do token.

Depois disso, basta configurar os parâmetros do SSL, mais ou menos assim

[code]System.setProperty(“javax.net.ssl.trustStoreType”, “JKS”);
System.setProperty(“javax.net.ssl.trustStore”, “C:\santri\nfe\nfe.jks”);

System.setProperty(“javax.net.ssl.keyStoreType”, “PKCS11”);
System.setProperty(“javax.net.ssl.keyStore”, “NONE”);
System.setProperty(“javax.net.ssl.keyStoreProvider”, “SunPKCS11-FeitianPKCS”);
System.setProperty(“javax.net.ssl.keyStoreAlias”, alias);
System.setProperty(“javax.net.ssl.keyStorePassword”, “12345678”);[/code]

Onde está 12345678, coloque a senha do seu token.

Eu vou disponibilizar os fontes com o teste simples. Qualquer dúvida, caso eu possa ajudar,
farei com prazer. Se eu lembrar de algo mais eu posto aqui.

Inté.

Cara, de tanto procurar na web, seu exemplo foi o que ficou jóia para mim, muito bem explicado, parabéns pelo trabalho.

Pessoal,

Sou novato neste forum e dou treinamento na certificação e emissão de notas fiscais eletronicas. Espero poder contribuir com os colegas.

Minha formação é de contabilidade por isso espero ainda contribuir com os desenvolvedores em quaisquer informações ligadas à contabilidade, pois também sou Analista de Sistemas.

Obrigado.

Odenir Campos
potencia.inf.br

[quote=marciosantri]Depois de muita luta com o token (A3) e muita ajuda do Alencar (philler),
consegui fazer a conexão com o servidor de NFe aqui de Goiás.
Para evitar que outros programadores Java sofram como eu, vou descrever mais ou menos
os principais problemas encontrados.

:arrow: Servidor Proxy
Se vc utiliza servidor proxy não se esqueça de colocar o parâmetro
-Dhttp.proxyHost=IP_SERVIDOR_PROXY -Dhttp.proxyPort=PORTA_PROXY
Vc corre o risco de perder um tempinho aí.

:arrow: Arquivo de Configuração do Token
A dll presente no CD da Pronova (caso do meu token) estava bem menor que a instalada em
meu computador. A Dll do CD simplesmente não funcionou. A que eu estou utilizando é
bem maior. Pode ser um índicio de problema.
Ainda no arquivo, fique atento ao nr. do slot e ao nome dado (este será utilizado posteriormente).
O meu arquivo ficou assim:

[quote]name = FeitianPKCS#11
library = C:\santri\nfe\token\ngp11v211.dll
slot = 1[/quote]

:arrow: Teste do Site da Sefaz
Tente acessar o site da Sefaz pelo IE (pelo Firefox não consegui salvar o WSDL direito)
e digite a senha do token. Se acessar, quer dizer que sua assinatura está apta à utilizar
os WebServices.
Salve o XML contendo o WSDL. No caso de Goiás, o endereço é
https://homolog.sefaz.go.gov.br/nfe/services/NfeStatusServico?WSDL
Você pode exportar o certificado (arquivo .cer) dando um duplo clique
no cadeado que aparece na parte inferior do IE. Salve este .cer (opção de 64 bits)
pois poderá ser útil (no meu caso foi).

:arrow: Gerando as classes do WebService
Para quem utiliza o Java 6, existe um utilitário chamado wsimport, muito bacana, que
já gera as classes para acessar o WebService da Sefaz.
Uma das vantagens do wsimport é que não precisa enviar outros .jars pois a tecnologia
de acesso já está no java 6.
O comando rodado (no prompt) é mais ou menos assim

wsimport -keep -p santri.nfe.ws.goias.homolog.status NfeStatusServico.xml

O programa wsimport está na pasta bin do Jre.
O parâmetro -p serve para indicar o pacote onde as classes serão geradas.
O último parâmetro identificar onde está o WSDL. Eu não conseguir colocando
o caminho https://homolog.sefaz.go.gov.br/nfe/services/NfeStatusServico?WSDL e
creio que deva ser por causa da autenticação. Por isso gerei o XML e o utilizei
aqui (deu na mesma).

:arrow: KeyStore
Me disseram que não precisa utilizar arquivo para definir KeyStore no certificado
A3. Bem, eu não consegui. O que consegui foi gerando o arquivo .jks.
Lembra-se do arquivo .cer exportado a uns tópicos acima? Pois bem, vamos utilizá-lo
agora.
No prompt de comando, digitar

keytool -importcert -file nfe.cer -keystore nfe.jks

nfe.cer é o nome do arquivo .cer exportado no IE.
nfe.jks é o arquivo a ser gerado.
Esse comando irá pedir uma senha. Basta digitá-la e confirmá-la.

:arrow: No Eclipse
No fonte, para realizar a conexão segura, será necessário registrar
o provider do token. Isto pode ser feito desta maneira:

public boolean configurarProvider(){ String configName = "C:\\santri\\nfe\\token\\pkcs11.cfg"; try { Provider p = new SunPKCS11(configName); Security.addProvider(p); } catch(Exception e) { e.printStackTrace(); return false; } return true; }

O “configName” é o arquivo contendo as configurações do token.

Também é necessário definir o “alias” do token.

Depois disso, basta configurar os parâmetros do SSL, mais ou menos assim

[code]System.setProperty(“javax.net.ssl.trustStoreType”, “JKS”);
System.setProperty(“javax.net.ssl.trustStore”, “C:\santri\nfe\nfe.jks”);

System.setProperty(“javax.net.ssl.keyStoreType”, “PKCS11”);
System.setProperty(“javax.net.ssl.keyStore”, “NONE”);
System.setProperty(“javax.net.ssl.keyStoreProvider”, “SunPKCS11-FeitianPKCS”);
System.setProperty(“javax.net.ssl.keyStoreAlias”, alias);
System.setProperty(“javax.net.ssl.keyStorePassword”, “12345678”);[/code]

Onde está 12345678, coloque a senha do seu token.

Eu vou disponibilizar os fontes com o teste simples. Qualquer dúvida, caso eu possa ajudar,
farei com prazer. Se eu lembrar de algo mais eu posto aqui.

Inté.[/quote]Eu também achei sua explicação muito boa, só queria fazer uma pergunta, antes daquele passo que você diz para acessar o endereço da Fazenda pelo IE você tem que instalar o certificado? (no meu caso é o A3 da Certsign que tem que baixar um gerenciador de certificado).

Sim, pois sem o certificado instalado você não consegue se comunicar com a SEFAZ.

Inté.

Caros, ainda estou planejando a implantação do sistema nfe em uma loja virtual, logo de cara e acho que com todos foi assim, é a dúvida em relação ao certificado digital. Em uma breve pesquisa, encontrei algumas empresas que vendem o certificado, ai veio a surpresa, existem uns 10 ou mais tipos de certificados… hehehe uns de hardware, outros de software, outros tipo token e etc.

A minha dúvida é a seguinte, qual seria o certificado para o meu caso? Irei fazer as emissões da seguinte forma:

Existirá uma Thread que ficará consultando no banco de dados os pedidos que estão no estágio aguardando emissão de nota, essa Thread então irá realizar a transmissão da nota e liberar o pedido.

Pelo que entendi, eu preciso do certificado A1 simples, aquele de 250 conto. Mas fiquei em dúvida se seria aquele certificado para servidor web de 1890 reais. Mas como vou fazer as transmissões via Thread não passarão pelo meu Apache, por isso acho que é a A1 simples.

Pergunto porque além de tudo está escrito que após escolhida a chave não é possível alterar… rsrsrs

Detalhe que o ambiente será Linux.

Obrigado.

Colegas,

Estamos desenvolvendo uma aplicacao web (.pnp + AJAX + MySql) e necessitamos validar os certificados A1 e A3 (tonken + leitora de cartao) e nao temos as rotinas prontas, ate porque o php nao faz isso.

Caso alguem ja tenha em Java ou codigo que possa ser incorporado ao .PHP, JavaScript, etc por favor entre em contato que podemos acertar um valor para que possa nos fornecer o codigo ok?

Desde ja agradeco o retorno, pois temos urgencia para estas rotinas.

Abraco a todos!

Adenildo Torres
adenildo.torres@admtransp.com.br
11-2685-1709
Nextel: 100*37781
11-8104-1063 (tim)

[quote=marciosantri]Depois de muita luta com o token (A3) e muita ajuda do Alencar (philler),
consegui fazer a conexão com o servidor de NFe aqui de Goiás.
Para evitar que outros programadores Java sofram como eu, vou descrever mais ou menos
os principais problemas encontrados.

[ sua solução e explicação de grande valia ]

Eu vou disponibilizar os fontes com o teste simples. Qualquer dúvida, caso eu possa ajudar,
farei com prazer. Se eu lembrar de algo mais eu posto aqui.

Inté.[/quote]

Muito obrigada por disponibilizar sua solução! Ela resolveu meu problema com a autenticação do certificado do servidor!

Bom dia,

Tenho um certiifcado pfx, executei todos esses procedimentos e não funcionou. Continua me dando o erro: HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target