Monday, February 07, 2011

Habilitando conexão Https c/ Java 'ignorando' o certificado

Frequentemente escrevo um código para realizar requisições entre aplicativos, seja para WS/REST ou mesmo um simples HttpClient, usando Https com Java. Como fazer uma requisição SSL sem registrar o certificado na JVM, ou mesmo um 'bypass' em certificado desconhecido?

Aqui deixo um exemplo de como realizar um requisição Https com Java ignorando o certificado. Usando X509TrustManager [mais sobre X509Certificate] e HostnameVerifier de fachada. Na verdade o uso do HostnameVerifier seria pra evitar java.io.IOException: HTTPS hostname wrong: should be ..., já que o nome do certificado não bate com o domínio.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package br.com.yaw.client.ssl.main;
 
import java.security.cert.X509Certificate;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
//...
 
public class TestSecureRequest {
 
  public static void main(String[] args) throws Exception  {
    final X509TrustManager cert = new X509TrustManager() {
      public X509Certificate[] getAcceptedIssuers() {
        return null;
      }
       
      public void checkServerTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
       
      public void checkClientTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
    };
 
    //cria socket ssl
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, new TrustManager[] { cert }, null);
 
    //ativa o socket para a requisicao
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
     
    final HostnameVerifier hv = new HostnameVerifier() {
      public boolean verify(String urlHostName, SSLSession session) {
        return true;
      }
    };
 
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
 
    // daqui pra frente o codigo que acionar WS/REST, ou um simples HttpClient
    //...
  }
}

Peace of cake.

@edermag
http://www.yaw.com.br/

5 comments:

Genius said...

Olá,

Estou tentando realizar uma conexão ssl desta forma mas estou obtendo o seguinte erro: Exception in thread "main" java.net.SocketException: Software caused connection abort: recv failed

Marcelo said...

Cara, muito obrigado! Você me ajudou muito!

Unknown said...

Muito obrigado amigo, me foi e muita utilidade seu artigo

Wagner said...

Eder, valeu demais estava com problemas para reconhecer um servidor Web Service em REST e voce me salvou.

Unknown said...

Seu artigo foi perfeito para o que eu estava precisando. Muito Obrigado!