NFe- Certificado A3 não tem jeito

20 respostas
L

Desenvolvi um sistema nfe … com o certificado a1 ele funciona certinho…porém com o certificado tipo A3 de cartão ele não funciona…sempre me retorna o “Error 403.7 Forbidden: SSl cliente certificate is required”

Estou com o certificado da caixa… que já me incomodei no passado com o do tipo A1 no qual tive que gerar um pfx com os certificados raizes que pra variar não vieram junto…creio que nesse caso seja a mesma coisa…porém não quero mecher no cartão do cliente…vai saber…

Tentei implementar algo utilizando exemplos que achei na internet…de adicionar esses certificados no cacerts usando uma classe chamada NFeBuildAllCacerts, no qual gera o arquivo NFeCacerts para efetuar consultas para todos os estados… e nessa classe tem os comandos

setCertFromFile("CertRaizCaixa"+File.separator + "ICP-Brasil.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA v1.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PJ v1.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PJ 1v1.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PF v1.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PF 1v1.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator + "ICP-Brasil v2.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA v2.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PF v2.cer", ks);
 setCertFromFile("CertRaizCaixa"+File.separator +"AC CAIXA PJ v2.cer", ks);

que no qual teoricamente deveria inserir os certificados que baixei do site da caixa para dentro do arquivo…

porém quando tento fazer uma consulta…o erro 403.7 persisite…

minha configuração de ajuste do ssl está assim

Provider p = new sun.security.pkcs11.SunPKCS11("SmartCard.cfg");
Security.addProvider(p);

 char[] pin =  senhaCertificadoCliente.toCharArray();
 KeyStore ks = KeyStore.getInstance("pkcs11", p);
 ks.load(null, pin);



             String alias = "";
            Enumeration<String> aliasesEnum = ks.aliases();
            while (aliasesEnum.hasMoreElements()) {
                alias = (String) aliasesEnum.nextElement();
                if (ks.isKeyEntry(alias)) break;
            }
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
System.setProperty("javax.net.ssl.keyStore", "NONE");
System.setProperty("javax.net.ssl.keyStoreProvider", p11ProviderName); // Tem q saber qual o provider dele (SmartCard, Safesig, etc).
System.setProperty("javax.net.ssl.keyStoreAlias", alias);
System.setProperty("javax.net.ssl.keyStorePassword", senhaCertificadoCliente);
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

System.setProperty("javax.net.ssl.trustStore", "NFeCacerts");//Aqui vem o arquivo criado através do comando keytool
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Também tentei utilizar a solução proposta aqui http://www.javac.com.br/jc/posts/list/376.page nas sem exito…
também nesse link http://www.javac.com.br/jc/posts/list/222-resolvendo-o-problema-4037-forbidden-para-certificado-a3-protocolsocketfactory.page mas também não funcionou… sempre o mesmo erro

Mas nada funciona…

Obs…não estou usando o axis para manipulação dos ws…e sim o jaxb e jaxws será que poderia ser isso o problema… pois todos as resoluções que vi…o pessoal estava usando o axis

20 Respostas

L

Será que teria como configurar dinamicamente o http no jaxws?

pois se implementar o comando antes de executar a consulta de status

Protocol protocol = new Protocol("https", socketFactoryDinamico, SSL_PORT);    
            Protocol.registerProtocol("https", protocol);

para criar um protocolo dinâmico de https… parece que o mesmo não surte efeito usando o jaxws

J

Já deu olha olhada aqui

http://www.javac.com.br/jc/posts/list/122-nfe-assinatura-dos-xmls-de-envio-de-lote-cancelamento-e-inutilizacao-certificado-a3.page

L

Bom…eu estou usando o certificado da caixa…que pra variar…naum veio o certificado raiz no cartão…

Meu problema seria mais na parte da consulta, pois uso o jax-ws…e não gero o xml de consulta, , é tudo o jax-ws que gera… ;;;
Por exemplo pra fazer a consulta, eu usaria isto

private static consultaStatus{
  try{
        System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");

		//ajustaSslCertificadoA1();
        if (!ajustaSslCertificadoA3()){
            return null;
        }

		NfeStatusServico2Soap12 consulta = new NfeStatusServico2().getNfeStatusServico2Soap12();

		NfeDadosMsg nfeDadosMsg = createNfeDadosMsg();

		Holder<NfeCabecMsg> nfeCabecMsg = new Holder<NfeCabecMsg>(createNfeCabecMsg());


		nfeConsultaNF2 = consulta.nfeStatusServicoNF2(nfeDadosMsg, nfeCabecMsg);

       
        return getRetorno((ElementNSImpl) nfeConsultaNF2.getContent().get(0));

       }catch(Exception ex){
            log.error(ex);
        }

        return null;


    }

}

private static NfeDadosMsg createNfeDadosMsg() {
		NfeDadosMsg dadosMsg = new NfeDadosMsg();

		ConsStatServ consStatServ = new ConsStatServ();
		consStatServ.setCUF(JENFeWS.cUF);
		consStatServ.setTpAmb(JENFeWS.tpAmb);
		consStatServ.setXServ("STATUS");

		dadosMsg.getContent().add(consStatServ);

		return dadosMsg;
	}

private static void ajustaSslCertificadoA1(){
        System.setProperty("javax.net.ssl.trustStoreType", "JKS");
        System.setProperty("javax.net.ssl.trustStore", "NFeCacerts");
      

		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
		System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
		System.setProperty("javax.net.ssl.keyStore", caminhoCertificadoCliente);
		System.setProperty("javax.net.ssl.keyStorePassword", senhaCertificadoCliente);

        System.setProperty("sun.security.ssl.allowUnsafeRenegotiation","true");
}

private static void ajustaSslCertificadoA3(){
    Provider p = new sun.security.pkcs11.SunPKCS11("SmartCard.cfg");  
    Security.addProvider(p);  
      
    char[] pin =  senhaCertificadoCliente.toCharArray();  
    KeyStore ks = KeyStore.getInstance("pkcs11", p);  
    ks.load(null, pin);  
      
      
      
                 String alias = "";  
                Enumeration<String> aliasesEnum = ks.aliases();  
                while (aliasesEnum.hasMoreElements()) {  
                    alias = (String) aliasesEnum.nextElement();  
                    if (ks.isKeyEntry(alias)) break;  
                }  
    System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");  
    System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");  
    System.setProperty("javax.net.ssl.keyStore", "NONE");  
    System.setProperty("javax.net.ssl.keyStoreProvider", p11ProviderName); // Tem q saber qual o provider dele (SmartCard, Safesig, etc).  
    System.setProperty("javax.net.ssl.keyStoreAlias", alias);  
    System.setProperty("javax.net.ssl.keyStorePassword", senhaCertificadoCliente);  
    System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");  
    System.setProperty("javax.net.ssl.trustStoreType", "JKS");  
      
    System.setProperty("javax.net.ssl.trustStore", "NFeCacerts");//Aqui vem o arquivo criado através do comando keytool  
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

e para setar os certificados no caso do tipo a1, ele funciona… pois no certificado a1, o pfx tem toda a cadeia da caixa daí é só setar
com o system.setProperty…que o jaxws pega…

o problema é esse certificado A3 da caixa que não veio com o certificados raiz… tentei gerar o cacerts com o certificado da caixa junto, mas parece que o jaxws não pega eles…só pega se estiver no certificado do cliente

teoricamente com o nfeCacerts carregado com os raizes da caixa deveria funcionar…
Só se existe alguma outra maneira de carregar os certificados da caixa

L

Como eu faço para setar um socketFactory no jaxws?

A

uma vez passei por isto, só funcionou quando inseri dentro do A3 toda a cadeia certificadora.

L

Grande aix… aí que tá…e como faz isso?.. tenho medo de detonar o cartão do cliente… he he he
Eu consigo acessar o cartão pelo programa charismatics da caixa

L

seria somente inserir os certificados raiz e os da caixa… e deixar o que está lá quieto…ou tem que fazer mais alguma coisa?

A

apenas jogue la a cadeia certificadora, não tem como estragar, e só não deletar nada rsrsrsrrs…

O

Se estes “certificados root” forem importados para o cacerts da JDK, não funciona? O cacerts da JDK fica em $JAVA_HOME/lib/security.

L

O estranho é que se eu instalar o certificado no explorer… junto com toda a cadeia certificadora…
Depois eu setar o ssl assim

System.setProperty("javax.net.ssl.keyStoreProvider", "SunMSCAPI");
System.setProperty("javax.net.ssl.keyStoreType", "Windows-MY");

ele funciona… só que cada consulta…ele pede senha e login

L

e como faz isso?
Oyama?

O

leopoldof:
e como faz isso?
Oyama?

É só usar o keytool e fazer um importcert da cadeia de certificados root para o $JAVA_HOME/lib/security/cacerts

http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html

L

obrigado vou ver aqui no link…e vou tentar importar e testar aqui…se funcionar … melhor…daí não prescisa mecher no cartão…daí é só fazer uma rotina para que faça esse import para o cacert na hora da instalação do sistema

L

Importando para o cacerts do java não funciona também…

F

Tem certeza que o problema são as raizes? O cartao esta funcionando mesmo? Tipo quando tu tenta fazer a consutla ele pisca a luz de acesso ao cartao pelo menos? Tem a questão da DLL que tem que ter na pasta system32 e tals.

Tirando a questão acima, ja passei por isto tambem, era um certificado do SERASA, tambem tentei colocar as cadeias dentro dele, não sei se fiz errado mas não consegui resolver.
E uns clientes com o mesmo certificado funcionava, ja um em especial não ia de jeito nenhum!

L

Se eu instalar os raizes no explorer e instalar o certificado também no explorer ele funciona… … então creio eu que o certificado está funcionando e os raizes também…
O problema de instalar do explorer é que toda hora o sistema gerenciador do leitor do cartao (no meu caso o charismatics) fica pedido a senha do cartão…isto é, deste jeito, quem gerencia o cartão , o certificado, inserção da senha não é meu sistema , e sim o charismatics …

Tenho quase certeza que se eu jogar os raizes dentro do cartão ele vai funcionar, como se fosse um certificado A1…certinho, onde meu sistema é quem gerencia as senhas do certificado…mas não sei se mecher com o cartão do cliente seria o correto … não sei se a caixa permite isso também,pois só mandam no cartão o certificado do cliente e não os raizes

A

leopoldof, com A3, ele vai de pedir o PIN, sempre, jah enroscamos com esse negocio um monte, caso consiga sera de grande valia pra todo mundo.

L

Pois é…sempre pede , mas isso quando busco o certificado do repositório do windows ,pois o gerenciador do leitor de cartão toma conta do negócio…

Creio que a única coisa que falta pra mim conseguir gerenciar toda a transação do cartão e tirar fora o gerenciador do leitor de lado é descobrir como utilizar os raizes da caixa sem eles estarem dentro do cartão A3 do cliente…

F

Nope, porque tu passa a senha do cartao no código java, meu sistema não pedia PIN toda vez não, claro, pode ser que cartoes/tokens diferentes tenham comportamentos diferentes. O meu era SERASA!

L

Ele pede o PIN sempre pois o certificado está instalado no repositorio do windows…lá no explorer…

Do outro jeito eu não consigo acessar o webservice, pois não tem os raizes dentro do cartão…então tenho que instalar tudo no explorer e fazer funcionar de lá…inclusive o certificado do cliente…
Se os raizes estivessem dentro do cartão daria para setar a senha direto via código

Criado 14 de fevereiro de 2012
Ultima resposta 28 de mar. de 2012
Respostas 20
Participantes 6