Validação de certificados digitais para hosts confiáveis (bypass)

Escrito por paulovittor23, 28 de Fevereiro de 2010 16:29

O erro abaixo ocorre quando tentamos chamar uma url HTTPS cujo Web Server não possui um certificado digital assinado por uma Autoridade Certificadora.

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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
…  (omitindo linhas do trace)
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:285)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191)
…  (omitindo linhas do trace)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
…  (omitindo linhas do trace)

Quando isto ocorre, existem duas abordagens possíveis para que o cliente do Web Server possa realizar a chamada HTTPS sem receber o erro acima apresentado.

São elas:

1 – Dar ao cliente um certificado dizendo que você aceita acessar o Web Server mesmo este não sendo reconhecido por uma Autoridade Certificadora.

Neste caso, os seguintes passos devem ser executados:

  • Salvar o certificado digital através de um browser (geralmente existe um cadeado no rodapé do browser que nos dá a opção de salvar o certificado);
  • Importar o certificado com o utilitário Keytool (que se encontra na pasta jre/bin);
  • Copiar o arquivo “.keystore” gerado;
  • Referenciá-lo em seu código.

2 – Fazer o cliente acessar qualquer url HTTPS sem validar o certificado digital do respectivo Web Server.

Neste caso, na aplicação cliente, devemos implementar um método que terá a responsabilidade de dar um bypass nessa validação.

public static void acceptSSL() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType
) {}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType
) {}
} };
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) { e.printStackTrace(); }
}

Este método deve ser invocado antes da chamada HTTPS, como no exemplo abaixo:


public static void main(String[] args) {
try {
acceptSSL();
String serviceData = callUrl( "https://somehost.com" );
System.out.println(serviceData);
} catch (IOException e) {
e.printStackTrace();
}
}

2 Comentários “Validação de certificados digitais para hosts confiáveis (bypass)”

  1. David Falcão diz:

    Caro Paulo Vitor, tudo bem?

    Então gostei bastante do seu resumo sobre o livro de Peopleware. Gostaria de saber se você autorizaria eu replicar os textos escritos por você para a turma de graduação onde dou aula. Estamos tratando justamente o tema Peopleware e o seu material está ótimo.

    Caso negativo, por favor me informe.

    Obrigado, e parabéns pelos textos!

  2. paulovittor23 diz:

    Caro David,
    Fico contente que tenha gostado da amostra do livro que publiquei.
    Fique a vontade em repassar o conteúdo.

    Um abraço.

Deixe o seu comentário!

Panorama Theme by Themocracy