Adicionando Autoridades Certificadoras (cacerts) no Java (JVM, JDK, JRE)

Quando uma JVM é instalada no computador através do JDK ou JRE também instala-se uma lista de autoridades certificadoras confiáveis (da mesma forma que ocorre ao instalar um navegador tipo google chrome, edge ou firefox).

Estes certificados de autoridades certificadoras são verificados pela JVM toda vez que uma conexão SSL/TLS é aberta. A conexão só é feita se o certificado enviado pelo servidor a qual a JVM quer conectar tiver sido assinado por uma autoridade certificadora confiável da lista, caso contrário o programa (Java, Kotlin, Groovy, Scala, Clojure) lançará uma exception durante a tentativa de conexão

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Se você estiver dentro de uma rede corporativa atrás de um firewall que inspeciona comunicações de rede TLS/SSL através de uma autoridade certificadora criada pela própria empresa (auto assinada) o programa também lançará a exception.

Se você estiver em um ambiente de teste utilizando certificados auto assinados para comunicação, também ocorrerá esta exception em algum momento.

Como resolver?

Há um arquivo com uma lista de todas as CAs confiáveis pela JVM e ela fica na sua pasta do java/lib/security/cacerts. Ela está em um formato próprio do java (JKS key store type) que é um formato binário e protegido por senha, então não é possível editá-la diretamente num editor de texto.

Para visualizar os certificados em um formato legível use o comando:

# -cacerts para se referir ao arquivo de CAs# -list para listar todos os certificados# -v para ver os certificados por completo (modo "verboso")keytool -list -v -cacerts# irá pedir uma senha, a senha padrão é "changeit" (sem aspas duplas)# Se você receber um erro comentando que -cacerts não é um parâmetro válido, tentekeytool -list -v -keystore /caminho.../java/security/cacerts

Para adicionar uma nova autoridade certificadora à lista do JDK/JRE, o certificado CA geralmente tem a extensão ".cer", mas o formato do arquivo é chamado de DER:

# -cacerts para se referir ao arquivo de CAs# -import para importar um novo certificado# -alias para dar nome ao novo certificado dentro da lista# -file para mostrar o caminho do arquivokeytool -import -alias meu-ca-confiavel -cacerts -file meu-ca-confiavel.cer# irá pedir uma senha, a senha padrão é "changeit" (sem aspas duplas)# Se você receber um erro comentando que -cacerts não é um parâmetro válido, troque -cacerts por -keystore /caminho.../cacertskeytool -import -alias meu-ca-confiavel -keystore /caminho.../java/security/cacerts -file meu-ca-confiavel.cer

Referências

Adicionando e visualizando CAs do Java
https://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed/
https://docs.microfocus.com/SM/9.41/Classic/Content/security/tasks/update_the_cacerts_keystore_file.htm

Sobre diferentes formatos de certificados
https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/

You should also read: