Apache Commons-httpclient [RESOLVIDO]

Pessoal, estou tentando reproduzir um post de formulário em uma página web via HttpClient, porém esta página possui SSL (https) e está me retornando o seguinte erro:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)

Alguém sabe como solucionar este problema?

Código:

String url = "https://www.siteexternoquenaotenhoacesso.com.br";
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(url);
int statusCode = -1;
statusCode = client.executeMethod(method);
if (statusCode == -1)
{
  System.err.println("Failed to recover from exception.");
  System.exit(-2);
}
byte[] responseBody = method.getResponseBody();
method.releaseConnection();
System.out.println(new String(responseBody));

fala santoro

voce precisa anexar o certificado digital SSL do site que voce está tentando acessar na sua JVM. Fiz isso uma vez, mas perdi aqui. Procurei rapidamente no google e achei isso:

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security6.html

Eu sei que tem um jeito de fazer isso dinamicamente também, se vc precisar, dá uma pesquisada.

boa sorte!

Mas este site que estou acessando é externo e não tenho acesso a ele, por exemplo:

https://sitenet11.serasa.com.br/login.htm

Não sei se é a melhor forma, mas funcionou e quero compartilhar a solução:

Via browser eu salvei o certificado em formato
Exemplo no IE
Clique duas vezes em cima do certificado vá na aba DETALHES
Clique em Copiar para arquivo…
Salve o arquivo como binário (*.cer)

No meu código java coloquei da seguinte maneira:

import java.io.*;
import java.security.*;
import javax.net.ssl.*;
import java.security.cert.*;

public class HTTPSClient
{
    static X509Certificate x509;
    static {
        try {
            CertificateFactory fact = CertificateFactory.getInstance("X.509");
            FileInputStream fis = new FileInputStream ("serasaacglobal.cer");
            x509 = (X509Certificate)fact.generateCertificate(fis);
            fis.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }    
    }
    
    static TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{
                    x509
                };
            }
            public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) {
            }
        }
    };
    private static int port = 443;                      
    private static String host = "sitenet11.serasa.com.br";  
    private static String path = "/login.htm";               

    public static void main(String[] args)
    {
        try
        {
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());

            // Connect to the server using an SSL socket
            SSLSocketFactory factory = sc.getSocketFactory(); // (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket socket = (SSLSocket) factory.createSocket(host, port);

            // Send HTTP GET message
            PrintWriter out = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
            out.println("GET "+path+" HTTP/1.1");
            out.println("Host: "+host);
            out.println("Connection: close");
            out.println("User-Agent: Java HTTPS Client");
            out.println("");
            out.flush();

            // Now dump server reply to console
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            int c;
            while ((c = in.read()) != -1)
            {
                System.out.write(c);
            }

            // All done, close io streams and socket
            out.close();
            in.close();
            socket.close();
        }
        catch (Exception e) { e.printStackTrace(); }
    }
}

Boa tarde,

santoro, estou tendo um problema parecido com o seu, só que ao ler o seu código percebi que você está simplesmente aceitando todos os certificados que o servidor mandar e não verificando os dados do servidor para garantir que o servidor que está respondendo é mesmo o dono do certificado.

Portanto se você remover a questão da utilização do certificado verá que sua página abre (pelo menos quando simulei consegui acessar a página), removi a chamada do certificado e também consegui acessar o site.

Se tentares rastrear verá que ele está executando somente o método checkServerTrusted que não faz nada, por tanto, se executar o fonte abaixo verá que ele abrirá o site.

Gostaria de saber se o seu caso é simplesmente uma aplicação SSL ou no caso exige autenticação mútua, que no caso é o meu problema, não estou conseguindo atribuir um certificado a uma conexão SSL.

[code]import java.io.;
import java.security.
;
import javax.net.ssl.;
import java.security.cert.
;

public class HTTPSClient
{
static TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
System.out.println("### - HTTPSClient.getAcceptedIssuers()");
return new java.security.cert.X509Certificate[]{
null
};
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
System.out.println("### - HTTPSClient.checkClientTrusted()");
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
System.out.println("### - HTTPSClient.checkServerTrusted()");
}
}
};
private static int port = 443;
private static String host = “sitenet11.serasa.com.br”;
private static String path = “/login.htm”;

public static void main(String[] args)
{
    try
    {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        // Connect to the server using an SSL socket
        SSLSocketFactory factory = sc.getSocketFactory(); // (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);

        // Send HTTP GET message
        PrintWriter out = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
        out.println("GET "+path+" HTTP/1.1");
        out.println("Host: "+host);
        out.println("Connection: close");
        out.println("User-Agent: Java HTTPS Client");
        out.println("");
        out.flush();

        // Now dump server reply to console
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        int c;
        while ((c = in.read()) != -1)
        {
            System.out.write(c);
        }

        // All done, close io streams and socket
        out.close();
        in.close();
        socket.close();
    }
    catch (Exception e) { e.printStackTrace(); }
}

}
[/code]

E sua saída será a seguinte:

[code]### - HTTPSClient.checkServerTrusted()
HTTP/1.1 200 OK
Date: Tue, 22 Jan 2008 18:19:15 GMT
Server: IBM_HTTP_SERVER
Last-Modified: Wed, 19 Sep 2007 17:26:17 GMT
ETag: “1e40b6-960-46f15bb9”
Accept-Ranges: bytes
Content-Length: 2400
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<!-- saved from url=(0041)https://sitenet11.serasa.com.br/login.htm -->
<HTML><HEAD><TITLE>Serasa</TITLE>
<META http-equiv=Content-Type content=“text/html; charset=iso-8859-1”>
<META http-equiv=Pragma content=no-cache>
<script language=“javascript” src="/js/jump.js"></script>
<link rel=“stylesheet” href=“http://www.serasa.com.br/elementos_estrutura/css/serasa.css” type=“text/css”>
<SCRIPT language=javascript>
var carga = true;
function enviar() {
if(carga){
carga=false;
document.forms[0].action = “Logon/Logon”
document.forms[0].submit();
} else {
alert(“Aguarde, a sua solicitação está sendo processada”);
}
}
</SCRIPT>

<META content=“MSHTML 6.00.6000.16481” name=GENERATOR></HEAD>
<BODY text=#000000 vLink=#000080 aLink=#000080 link=#000080 bgColor=#ffffff
onload=document.frmPri.LOGON.focus()>
<TABLE cellSpacing=0 cellPadding=0 width=400
background=http://www.serasa.com.br/elementos_estrutura/img/fundo_linhas.jpg border=0>
<FORM name=frmPri action=javascript:enviar(); method=post target=_top>
<DIV align=right><INPUT type=hidden value=1 name=NOVASESSAO> <INPUT
type=hidden value=2 name=FLAGCERT> </DIV>
<TBODY>
<TR>
<TD class=menu-barra-superior width=“28%” height=20> </TD>
<TD class=menu-barra-superior width=“11%”> </TD>
<TD class=menu-barra-superior width=“8%”><span
class=style1>Login</span></TD>
<TD class=menu-barra-superior width=“15%” height=20><INPUT
onkeyup=“JumpField(this.form.name, this.name, 8)” maxLength=8 size=8
name=LOGON></TD>
<TD class=menu-barra-superior width=“11%” height=20><SPAN
class=style1>Senha</SPAN></TD>
<TD class=menu-barra-superior width=“13%” height=20><INPUT
onkeyup=“JumpField(this.form.name, this.name, 8)” type=password
maxLength=8 size=8 name=SENHA> </TD>
<TD class=menu-barra-superior width=“14%” height=20><SPAN
style=“CURSOR: hand”><INPUT id=teste style=“CURSOR: hand”
onclick=javascript:enviar(); type=image alt=OK
src=“http://www.serasa.com.br/elementos_estrutura/img/ok.gif” value=OK></SPAN></TD></TR>
<DIV></DIV></FORM><tr><td colspan=“3”></TBODY></TABLE>
</BODY></HTML>
[/code]

Ats,
Endrigo Antonini