2
respostas

Certificado SSL

Como adicionar o certificado do servidor ao truststore do Java ?

2 respostas

Oii, Osmar, tudo bem?

Para adicionar o certificado do servidor ao truststore do Java, você pode seguir os seguintes passos:

  • Obtenha o Certificado SSL do Servidor: primeiro, você precisa obter o certificado SSL do servidor ao qual deseja se conectar. Isso pode ser feito acessando o servidor via navegador e exportando o certificado, ou utilizando ferramentas como o OpenSSL para obter o certificado diretamente do servidor.

  • Adicione o Certificado ao Truststore do Java:

    • Localize o arquivo cacerts que é o truststore padrão do Java. Normalmente, ele está localizado em JAVA_HOME/lib/security/cacerts.
    • Utilize o comando keytool para adicionar o certificado ao truststore. Aqui está um exemplo de como você pode fazer isso:
      keytool -import -alias server -file [caminho_do_certificado] -keystore [caminho_do_truststore] -storepass [senha]
      
      Substitua [caminho_do_certificado] pelo caminho do arquivo de certificado que você exportou, [caminho_do_truststore] pelo caminho completo do arquivo cacerts, e [senha] pela senha do truststore (a senha padrão geralmente é changeit).
  • Verifique se o Certificado foi Adicionado:

    • Você pode verificar se o certificado foi adicionado ao truststore utilizando o seguinte comando:
      keytool -list -keystore [caminho_do_truststore] -storepass [senha]
      
    • Procure pelo alias que você usou ao adicionar o certificado (neste caso, server) na lista que aparece.

Se outra dúvida surgir, estamos aqui.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Boa tarde Maria Isabel,

Obrigado pela atenção, mas ainda estou com um problema relativo ao certificado.

Vou dar o contexto geral do meu problema que talvez possa agregar um conhecimento mais avançado ao curso, quem sabe no tópico "Para Saber Mais".

É o seguinte:

Estou fazendo uma integração com o banco Cora e foi me passado uma senha (client_id) e dois arquivos (um certificado .pem e uma chave privada .key).

A requisição para obter o token JWT foi realizada com sucesso no Postman com os dados referidos anteriormente.

Para implementar no Spring Boot, primeiro eu gerei uma chave PKCS12 através do comando:

$openssl pkcs12 -export -inkey private-key.key -in certificate.pem -out certificado.p12 -name "banco-cora"

Adicionei o certificado "certificate.pem" ao Truststore do java como vc me ensinou

Mesmo assim ainda continuo recebendo o seguinte erro: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Abaixo segue a classe responsável pela geração do token:


import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import br.com.nautico.api.dto.cobranca.TokenCobanca;
import br.com.nautico.api.exception.ApiException;
import kong.unirest.HttpResponse;
import kong.unirest.JsonNode;
import kong.unirest.Unirest;
import lombok.extern.java.Log;

@Service
@Log
public class CobrancaCoraService {
    
    @Value("${cora.api}")
    private String urlBase; 
    
    @Value("${cora.client.id}")
    private String clientId; // client_id enviada pelo banco

    @Value("${cora.certificado}")
    private String certificado;  // certificado .p12
    
    @Value("${cora.chavePKCS12}")
    private String chavePKCS12; // senha informada na criação do certificado .p12 
    
      
    public TokenCobanca obterToken() {
        log.info("Banco CORA - Obter token (credenciais)");
        
        SSLContext sslContext = createSSLContext(certificado);
        Unirest.config().sslContext(sslContext);
        var token = requestBancoCora();        
        
        log.info("Banco CORA - Token gerado com sucesso!");
        return token;
    }

    private TokenCobanca requestBancoCora() {
        try {
            String url = urlBase + "/token";
            
            HttpResponse<JsonNode> response = Unirest.post(url)
                    .header("Content-Type", "application/x-www-form-urlencoded")
                    .field("grant_type", "client_credentials")
                    .field("client_id", clientId)
                    .asJson();
            
            JsonNode body = response.getBody();
            var token = new TokenCobanca(
                    body.getObject().getString("access_token"),
                    body.getObject().getString("business_id"),
                    body.getObject().getString("person_id")
                    );

            return token;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiException("Não foi possível o acesso ao banco Cora! %s".formatted(e.getCause()));
        }
    }        
    
    private SSLContext createSSLContext(String certPath) {
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream certInput = new FileInputStream(certPath);
            keyStore.load(certInput, chavePKCS12.toCharArray());
            
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new java.security.SecureRandom());
            
            return sslContext;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiException("Não foi possível validar as credenciais! %s".formatted(e.getCause()));
        }
    }
    
}