javax.net.ssl.SSLHandshakeException aplicação não encontra cadeia de certificados

REST

Java

JSON

29/01/2020

Estou enviando um json para servidor Rest, gerando a seguinte exceção

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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
	at sun.net.www.protocol.http.HttpURLConnection.
Grave:   getInputStream(HttpURLConnection.java:1492)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
	at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:240)
	at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
	... 59 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(PKIXValidator.java:397)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
	at sun.security.validator.Validator.validate(Validator.java:262)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
	... 74 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
	... 80 more


Já pesquisei em fóruns, que orientavam a importar o arquivo crt para cacert do java, o que já fiz mas sem sucesso

keytool –importcert –trustcacerts –alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit
Bruno Andrade

Bruno Andrade

Curtidas 0

Respostas

Estevão Dias

Estevão Dias

29/01/2020

Oi Bruno, tudo bom?

Esse erro pode estar em vários lugares, então é melhor se a gente for eliminando as possibilidades uma a uma com testes, certo? Pode ser um problema na configuração do certificado (comandos que você usou), versão do JDK (algumas vezes é preciso atualizar pra última versão do JDK 8) ou configuração do servidor de aplicação/web.

Então, a primeira coisa que eu faria seria rever a documentação do certificado na empresas reguladora pra confirmar se a configuração dele no computador está correta.

Depois eu verificaria o servidor, você está usando o Tomcat? É possível pra você compartilhar a sua configuração de certificado?

Por último, tente verificar se o erro persiste na última versão do JDK, as vezes é preciso checar em mais de uma versão.

Às vezes usar dispositivos diferentes para as chamadas pode ajudar a rastrear o problema, por exemplo, fazer a chamado do Postman e do seu smartphone.

Checa isso e me retorna, por favor. To no aguardo.

Estou enviando um json para servidor Rest, gerando a seguinte exceção

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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
	at sun.net.www.protocol.http.HttpURLConnection.
Grave:   getInputStream(HttpURLConnection.java:1492)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
	at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:240)
	at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147)
	... 59 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(PKIXValidator.java:397)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
	at sun.security.validator.Validator.validate(Validator.java:262)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
	... 74 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
	... 80 more


Já pesquisei em fóruns, que orientavam a importar o arquivo crt para cacert do java, o que já fiz mas sem sucesso

keytool –importcert –trustcacerts –alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit
GOSTEI 0
Marcio Souza

Marcio Souza

29/01/2020

Olá Bruno.

Geralmente esse erro ocorre quando você tem uma aplicação Java que tenta se comunicar com um site via protocolo HTTPS. Como sua aplicação Java não tem o certificado de segurança (SSL) para acessar esse site, a sua instalação do Java (JRE) vai lançar a exceção. Então, você precisa baixar e instalar esse certificado na sua instalação do Java.

Para que esse comando que você postou funcione é necessário que você tenha o certificado do site que está tentando acessar para então importa-lo para a base de certificados do Java: C:\\Program Files\\Java\\jre1.8.0_241\\lib\\security\\cacerts

Se você não sabe fazer o download do certificado, de uma olhada nesse tutorial:
- https://conube.zendesk.com/hc/pt-br/articles/115000202266-Como-exportar-o-certificado-digital-da-minha-empresa-pelo-Goggle-Chrome

Depois de baixar o certificado abra o terminal de linha de comando e execute:
keytool –importcert –trustcacerts –alias <apelido> -file <caminho para o certificado .crt> -keystore <caminho para o cacerts> -storepass changeit

O comando keytool é distribuído junto com o pacote JRE e você vai substituir as seguintes instruções por aquilo que é necessário:
<apelido>: Nome qualquer para identificar o certificado a ser instalado na base (pode ser o próprio nome do site)
<caminho para o certificado .crt>: Caminho onde foi salvo o certificado baixado do site
<caminho para o cacerts>: "C:\\Program Files\\Java\\jre1.8.0_241\\lib\\security\\cacerts" ou aquele referente a sua instalação
<-storepass changeit>: "changeit" essa é a senha padrão para manipulação da base de certificados java (cacerts)
GOSTEI 0
Bruno Andrade

Bruno Andrade

29/01/2020

Olá Bruno.

Geralmente esse erro ocorre quando você tem uma aplicação Java que tenta se comunicar com um site via protocolo HTTPS. Como sua aplicação Java não tem o certificado de segurança (SSL) para acessar esse site, a sua instalação do Java (JRE) vai lançar a exceção. Então, você precisa baixar e instalar esse certificado na sua instalação do Java.

Para que esse comando que você postou funcione é necessário que você tenha o certificado do site que está tentando acessar para então importa-lo para a base de certificados do Java: C:\\\\Program Files\\\\Java\\\\jre1.8.0_241\\\\lib\\\\security\\\\cacerts

Se você não sabe fazer o download do certificado, de uma olhada nesse tutorial:
- https://conube.zendesk.com/hc/pt-br/articles/115000202266-Como-exportar-o-certificado-digital-da-minha-empresa-pelo-Goggle-Chrome

Depois de baixar o certificado abra o terminal de linha de comando e execute:
keytool –importcert –trustcacerts –alias <apelido> -file <caminho para o certificado .crt> -keystore <caminho para o cacerts> -storepass changeit

O comando keytool é distribuído junto com o pacote JRE e você vai substituir as seguintes instruções por aquilo que é necessário:
<apelido>: Nome qualquer para identificar o certificado a ser instalado na base (pode ser o próprio nome do site)
<caminho para o certificado .crt>: Caminho onde foi salvo o certificado baixado do site
<caminho para o cacerts>: "C:\\\\Program Files\\\\Java\\\\jre1.8.0_241\\\\lib\\\\security\\\\cacerts" ou aquele referente a sua instalação
<-storepass changeit>: "changeit" essa é a senha padrão para manipulação da base de certificados java (cacerts)


Boa tarde

Já baixei a cadeia de certificados que peguei na documentação (link abaixo) e adicionei no arquivo carcert do Java jdk 1.8.0_241 pelo utilitário keytool.

https://focusnfe.com.br/doc/#introducao_ambiente

keytool -importcert –trustcacerts -file "C:\\Users\\bruno.vieira\\Documents\\ca.crt" -alias nfse -keystore "C:\\Program Files\\Java\\jdk1.8.0_241\\jre\\lib\\security\\cacerts"

Testei com duas versões da jdk, a atual 241 e a 191.

O servidor que utilizamos é o Glassfish 4.

Já fiz o teste também no nosso sistema em produção que tem certificado válido e está com versão jdk 1.8.0_101.

Mesmo assim ainda persiste o erro.

Estou fazendo testes no meu ambiente local que não tem certificado válido SSL, tem alguma coisa haver?

Trecho do código que peguei na documentação:

public String nfseConsulta() {
        String login = "XXXXXXXXXXXXXXXXXXXXXXXXXX";

        /* Substituir pela sua identificação interna da nota. */
        String ref = "77477";

        /* Para ambiente de produção use a variável abaixo:*/        
        String server = "https://homologacao.focusnfe.com.br/";

        String url = server.concat("v2/nfse/" + ref);

        /* Configuração para realizar o HTTP BasicAuth. */
        Object config = new DefaultClientConfig();
        Client client = Client.create((ClientConfig) config);
        client.addFilter(new HTTPBasicAuthFilter(login, ""));

        WebResource request = client.resource(url);

        ClientResponse resposta = (ClientResponse) request.get(ClientResponse.class);

        int httpCode = resposta.getStatus();

        String body = resposta.getEntity(String.class);

        /* As três linhas abaixo imprimem as informações retornadas pela API.
         * Aqui o seu sistema deverá interpretar e lidar com o retorno. */
        System.out.print("HTTP Code: ");
        System.out.print(httpCode);
        System.out.printf(body);
        return null;
    }

GOSTEI 0
Bruno Andrade

Bruno Andrade

29/01/2020

Boa tarde

Já baixei a cadeia de certificados que peguei na documentação (link abaixo) e adicionei no arquivo carcert do Java jdk 1.8.0_241 pelo utilitário keytool.

https://focusnfe.com.br/doc/#introducao_ambiente

keytool -importcert –trustcacerts -file "C:\\\\Users\\\\bruno.vieira\\\\Documents\\\\ca.crt" -alias nfse -keystore "C:\\\\Program Files\\\\Java\\\\jdk1.8.0_241\\\\jre\\\\lib\\\\security\\\\cacerts"

Testei com duas versões da jdk, a atual 241 e a 191.

O servidor que utilizamos é o Glassfish 4.

Já fiz o teste também no nosso sistema em produção que tem certificado válido e está com versão jdk 1.8.0_101.

Mesmo assim ainda persiste o erro.

Estou fazendo testes no meu ambiente local que não tem certificado válido SSL, tem alguma coisa haver?

Trecho do código que peguei na documentação:

public String nfseConsulta() {
        String login = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
 
        /* Substituir pela sua identificação interna da nota. */
        String ref = "77477";
 
        /* Para ambiente de produção use a variável abaixo:*/        
        String server = "https://homologacao.focusnfe.com.br/";
 
        String url = server.concat("v2/nfse/" + ref);
 
        /* Configuração para realizar o HTTP BasicAuth. */
        Object config = new DefaultClientConfig();
        Client client = Client.create((ClientConfig) config);
        client.addFilter(new HTTPBasicAuthFilter(login, ""));
 
        WebResource request = client.resource(url);
 
        ClientResponse resposta = (ClientResponse) request.get(ClientResponse.class);
 
        int httpCode = resposta.getStatus();
 
        String body = resposta.getEntity(String.class);
 
        /* As três linhas abaixo imprimem as informações retornadas pela API.
         * Aqui o seu sistema deverá interpretar e lidar com o retorno. */
        System.out.print("HTTP Code: ");
        System.out.print(httpCode);
        System.out.printf(body);
        return null;
    }

GOSTEI 0
POSTAR