Validação de certificados digitais para hosts confiáveis (bypass) — Blog do PV

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

Posted by paulovittor23 at 28 Fevereiro 2010

Category: Java, Segurança

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();
}
}

3 Comentários

  1. David Falcão says

    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 says

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

    Um abraço.

  3. Edson says

    Paulo,

    Estava com esse problemão há bastante tempo e seu artigo veio salvando. Valeu pela ajuda.

Deixar uma resposta

Deixar uma resposta
  • (obrigatório)
  • (obrigatório) (will not be published)
  • *