ERRO SSL Provider:SunJSSE

19 respostas
CoringadoBatman

Bom dia Pessoal,

Estou na luta com a Nfs-e, mas não sou um desenvolvedor java. Na verdade trabalho com outra ferramenta que compila em java, por isso talvez seja uma dúvida um pouco tranquila para ser respondida.
E se alguém consegui me dar uma dica, ou me passar um passo a passo de como preparo o TOMCAT e o Java para usar os protocolos SSL, e o que devo setar para conseguir comunicação com um servidor que me exija certificado digital para assinar o acesso.

javax.servlet.ServletException: java.lang.RuntimeException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)(-10001)

at SdtServiceGinfesImplService.consultarsituacaoloterpsv3(SdtServiceGinfesImplService.java:1646)

at xmlteste_impl.e110G2(xmlteste_impl.java:458)

at xmlteste_impl.evt0G2(xmlteste_impl.java:326)

at xmlteste_impl.dispatchEvents(xmlteste_impl.java:207)

at appmasterpage_impl.evt012(appmasterpage_impl.java:248)

at appmasterpage_impl.ws012(appmasterpage_impl.java:154)

at appmasterpage_impl.webExecute(appmasterpage_impl.java:55)

at xmlteste_impl.webExecute(xmlteste_impl.java:94)

at com.genexus.webpanels.GXWebObjectBase.doExecute(Unknown Source)

at xmlteste.doExecute(xmlteste.java:30)

at com.genexus.webpanels.GXWebObjectStub.callExecute(Unknown Source)

at com.genexus.webpanels.GXWebObjectStub.doPost(Unknown Source)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

at org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java:419)

at org.apache.catalina.servlets.InvokerServlet.doPost(InvokerServlet.java:169)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)

at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)

at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)

at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)

at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)

at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)

at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)

at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)

at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)

at java.lang.Thread.run(Thread.java:619)

Desde já fico grato

19 Respostas

CoringadoBatman

Preciso configurar meu certificado digital, tentei usar o Keytool e configurar o server.xml
Mas sem sucesso.

Ainda estou com o mesmo problema

CoringadoBatman

Consegui através da Keytool e server.xml
algumas configurações…
mas continuo com erro, agora está o seguinte

javax.servlet.ServletException: java.lang.RuntimeException: Connection has been shutdown: 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(-10001)
at SdtServiceGinfesImplService.consultarsituacaoloterpsv3(SdtServiceGinfesImplService.java:1646)

:frowning:

aix

CoringadoBatman:
Consegui através da Keytool e server.xml
algumas configurações…
mas continuo com erro, agora está o seguinte

javax.servlet.ServletException: java.lang.RuntimeException: Connection has been shutdown: 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(-10001)
at SdtServiceGinfesImplService.consultarsituacaoloterpsv3(SdtServiceGinfesImplService.java:1646)

:frowning:

geralmente tinha este erro quando não instalava o certificado na aplicação, rode a installCert ela vai gerar um arquivo que contem as chaves, depois só indique onde se encontra o arquivo de chaves.

public class InstallCert {

    public static void main(String[] arg) throws Exception {
        List<String> hostList = new ArrayList<String>();
        hostList.add("nfe.sefaz.ba.gov.br");
        hostList.add("nfe.sefaz.am.gov.br");
        hostList.add("nfe.sefaz.ce.gov.br");
        hostList.add("nfe.sefaz.go.gov.br");
        hostList.add("nfe.fazenda.mg.gov.br");
        hostList.add("nfe.fazenda.ms.gov.br");
        hostList.add("nfe.sefaz.mt.gov.br");
        hostList.add("nfe.sefaz.pe.gov.br");
        hostList.add("nfe2.fazenda.pr.gov.br");
        hostList.add("nfe.sefaz.rs.gov.br");
        hostList.add("nfe.fazenda.sp.gov.br");
        hostList.add("sef.sefaz.rs.gov.br");
        hostList.add("www.sefazvirtual.fazenda.gov.br");
        hostList.add("nfe.sefazvirtual.rs.gov.br");
        for (String host : hostList) {
            instala(host);
        }
    }

    public static void instala(String host) throws Exception {
        // Cria o arquivo onde serão adicionados os certificados.
        String trustStoreName = "trust_store_nfe";  //nome do arquiov gerado
        File file = new File(trustStoreName);
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security");
            file = new File(dir, trustStoreName);
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("*** " + host + " no arquivo " + file.getAbsolutePath() + " ***");

        int port = 443;
        char[] passphrase = "changeit".toCharArray();

        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[]{tm}, null);
        SSLSocketFactory factory = context.getSocketFactory();

        // Comunica-se com o servidor para obter os certificados.
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            socket.startHandshake();
            socket.close();
        } catch (SSLException e) {
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("*** Could not obtain server certificate chain");
            return;
        }

        // Processa cada um dos certificados recebidos na cadeia do servidor.
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            sha1.update(cert.getEncoded());
            md5.update(cert.getEncoded());
        }

        int k = 0;
        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream(trustStoreName);
        ks.store(out, passphrase);
        out.close();
        System.out.println("*** Added certificate to keystore '" + trustStoreName + "' using alias '" + alias + "'");
    }
    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            throw new UnsupportedOperationException();
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }
}

properties

System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
        System.clearProperty("javax.net.ssl.keyStore");
        System.clearProperty("javax.net.ssl.keyStorePassword");
        System.clearProperty("javax.net.ssl.trustStore");
        System.setProperty("javax.net.ssl.keyStore", caminhoCertificado);
        System.setProperty("javax.net.ssl.keyStorePassword", senhaCertificado);
        System.setProperty("javax.net.ssl.trustStoreType", "JKS");
        if (!Tools.FileSystem.exists("trust_store_nfe")) {
            File file = new File(".");
            throw new Throwable("O arquivo de chaves da aplicação não foi encontrado na pasta " + file.getCanonicalPath());
        }
        System.setProperty("javax.net.ssl.trustStore", "trust_store_nfe"); //este é o arquivo gerado pela InstallCert
CoringadoBatman

Ainda assim não consegui, agora deu erro no meu arquivo .keytool

Não sei se criei corretamente.
Tem como criar a partir de um PFX?

e um .jks tem como criar também a partir de um .pfx?

Grato

aix

CoringadoBatman:
Ainda assim não consegui, agora deu erro no meu arquivo .keytool
Não sei se criei corretamente.
Tem como criar a partir de um PFX?
e um .jks tem como criar também a partir de um .pfx?
Grato

com esta classe não precisa mais nada, esqueça todo resto.

rode a classe, ela ira gerar seu arquivo de chaves(keytool) que demos o nome de trust_store_nfe, ele gera o arquivo na raiz da aplicação, depois é só configurar nas properties System.setProperty(“javax.net.ssl.trustStore”, “trust_store_nfe”);

CoringadoBatman

Não consegui implementar essa classe não.
Sou iniciante em java, até pra fazer uma classe me bato
trabalho com um robot que compila em java, por isso preciso usar o keytool
até fiz sua classe mas não consegui importar

aix

CoringadoBatman:
Não consegui implementar essa classe não.
Sou iniciante em java, até pra fazer uma classe me bato
trabalho com um robot que compila em java, por isso preciso usar o keytool
até fiz sua classe mas não consegui importar

aqui tem um exemplo que acredito que possa te ajudar, se mesmo assim não der posta ai o erro para que a gente veja se conseguimos te ajudar.

CoringadoBatman
java System.setProperty(javax.net.ssl.trustStore, C:/Certificados/xxx.jks);

java System.setProperty(javax.net.ssl.trustStorePassword, xxx);

java System.setProperty(javax.net.ssl.keyStore, xxx.ks);

java System.setProperty(javax.net.ssl.keyStorePassword, xxx);
server.xml(TOMCAT)

Connector port=8443

maxThreads=150 minSpareThreads=25 maxSpareThreads=75

enableLookups=false disableUploadTimeout=true

acceptCount=100 keystoreFile=C:\Certificados\xxx.jks keystorePass=xxx debug=0 scheme=https secure=true

clientAuth=false sslProtocol=TLS />

.ks criado assim
keytool.exe -import -alias Xxx -keystore Xxx.ks -file C:\Certificados\Xxx.cer
.jks
keytool.xex -import -alias Xxx -keytore C:\Certificados\cer\Xxx.jks -file C:\Certificados\cer\Xxx.cer

Importei no Browser no Root Trusted certificade bla bla bla também o .cer e o .pfx

Ai rodo minha aplicação pela porta 8443 ex: https://localhost:8443/minhaaplicação

E ele me retorna:

javax.servlet.ServletException: java.lang.RuntimeException: Connection has been shutdown: 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(-10001)

at SdtServiceGinfesImplService.consultarsituacaoloterpsv3(SdtServiceGinfesImplService.java:1646)

at xmlteste_impl.e110G2(xmlteste_impl.java:462)

at xmlteste_impl.evt0G2(xmlteste_impl.java:326)

at xmlteste_impl.dispatchEvents(xmlteste_impl.java:207)

at appmasterpage_impl.evt012(appmasterpage_impl.java:248)

at appmasterpage_impl.ws012(appmasterpage_impl.java:154)

at appmasterpage_impl.webExecute(appmasterpage_impl.java:55)

at xmlteste_impl.webExecute(xmlteste_impl.java:94)

at com.genexus.webpanels.GXWebObjectBase.doExecute(Unknown Source)

at xmlteste.doExecute(xmlteste.java:30)

at com.genexus.webpanels.GXWebObjectStub.callExecute(Unknown Source)

at com.genexus.webpanels.GXWebObjectStub.doPost(Unknown Source)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

at org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java:419)

at org.apache.catalina.servlets.InvokerServlet.doPost(InvokerServlet.java:169)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

Continua

Mesmo assim, estou lendo aquela documentação que me passou! Obrigado!

CoringadoBatman

AIX

Li seu tutorial e realmente(pelo tutorial) fiz tudo certinho.
Com o certificado, exportei, fiz o keystore

mas ainda continuo com o erro citado acima, tem mais alguma dica? Qualquer dica que eu investigo… (desespero!)
Haha

Ou se tiver alguma coisa sobre NFS-e GISSONLINE

valew

aix

CoringadoBatman:
AIX

Li seu tutorial e realmente(pelo tutorial) fiz tudo certinho.
Com o certificado, exportei, fiz o keystore

mas ainda continuo com o erro citado acima, tem mais alguma dica? Qualquer dica que eu investigo… (desespero!)
Haha

Ou se tiver alguma coisa sobre NFS-e GISSONLINE

valew

coloca o arquivo de chaves na pasta bin do java que funciona java/jdk/jre/bin

CoringadoBatman

Acho que agora so falta setar alguma coisa na aplicação o browser já está reconhecendo o certificado

java System.setProperty(javax.net.ssl.trustStore, C:/Certificados/cer/Xxx.jks);

java System.setProperty(javax.net.ssl.trustStorePassword, xxx);

java System.setProperty(javax.net.ssl.keyStore, Xxx.ks);

java System.setProperty(javax.net.ssl.keyStorePassword, xxx);

Falta setar alguma coisa?

aix

CoringadoBatman:
Acho que agora so falta setar alguma coisa na aplicação o browser já está reconhecendo o certificado

java System.setProperty(javax.net.ssl.trustStore, C:/Certificados/cer/Xxx.jks);

java System.setProperty(javax.net.ssl.trustStorePassword, xxx);

java System.setProperty(javax.net.ssl.keyStore, Xxx.ks);

java System.setProperty(javax.net.ssl.keyStorePassword, xxx);

Falta setar alguma coisa?

o passo acima funcionou ? qual é o erro agora ?

CoringadoBatman

O erro ainda é o mesmo, consegui fazer o tomcar conectar assim com
https://localhost:8443

E antes o certificado dava que estava com erro, mas agora esta ok.

Mas quando conecto a plicação ainda permanece o erro.
Não sei se estou setando corretamente.

o .ks não tem que ser .keystore?

Onde deve armazenar o .ks e o .jks?

aix

CoringadoBatman:
O erro ainda é o mesmo, consegui fazer o tomcar conectar assim com
https://localhost:8443

E antes o certificado dava que estava com erro, mas agora esta ok.

Mas quando conecto a plicação ainda permanece o erro.
Não sei se estou setando corretamente.

o .ks não tem que ser .keystore?

Onde deve armazenar o .ks e o .jks?

sim 8443 é porque vc habilitou ssl na sua aplicação, para consumir um WS não era necessario.

seu unico problema que vejo esta com o arquivos de chaves, ele diz que não encontra o arquivo, aquela classe que te mandei faz o serviço.

CoringadoBatman

Hummmmmmm
Muito intereçante isso.
Peguei o manual do keytool(todo em inglês) demora um pouco mais mas nem que eu tenha que comer!

Mais uma pergunta.

Eu tenho o .pfx(originalmente)
ai a partir do browser exportei e criei um .cer

a partir deste .cer criei o .ks e o jks

é isso mesmo? E esta na pasta bin dentro do jdk/jre/bin

Não sei nem como agradecer a ajuda!

CoringadoBatman

Mais uma pergunta…

Na verdade a curcial.

COMO INSTALAR UM CERTIFICADO .PFX EM UM AMBIENTE

JAVA,TOMCAT

SEM USAR CLASSES JAVA?

Acho que agora sei o que preciso!(antes era meio que na bola de cristal)

aix

CoringadoBatman:
Mais uma pergunta…

Na verdade a curcial.

COMO INSTALAR UM CERTIFICADO .PFX EM UM AMBIENTE

JAVA,TOMCAT

SEM USAR CLASSES JAVA?

Acho que agora sei o que preciso!(antes era meio que na bola de cristal)

não é assim que funciona, não tem que instalar um arquivo .pfx no java nem no tomcat, o certificado(arquivo.pfx) é para poder se autenticar no Webservice que vai consumir que é https.
por padrão vc faz requisições http, para consumir o WS que é https você precisa habilitar sua aplicação a fazer requisições https, que é o serviço que a classe acima faz, ela habilita que você faça request https.

CoringadoBatman

Humm, e tem alguma outra maneira de fazer isso sem usar essa classe?
ou devo fazer pelo sistema?
(tentei gerar essa classe mas sem sucesso, desculpe minha falta de conhecimento)

aix

CoringadoBatman:
Humm, e tem alguma outra maneira de fazer isso sem usar essa classe?
ou devo fazer pelo sistema?
(tentei gerar essa classe mas sem sucesso, desculpe minha falta de conhecimento)

tranquilo brother não tem do que se diculpar, apanhei muito também na NFe, CTe etc… pode usar o keytool para criar o arquivo de chaves, mas a classe simplifica todo o processo, com ela não precisa ir la pro MS-DOS ficar adicionando as cadeias dos certificados.

Criado 17 de janeiro de 2012
Ultima resposta 18 de jan. de 2012
Respostas 19
Participantes 2