'https' com framework HttpClient

1 resposta
ssousuke

Ola,

preciso acessar uma URL que utiliza https usando o framework HttPClient da jakarta ( http://hc.apache.org/httpclient-3.x/sslguide.html )… mas não entendo nada de “https” (a não ser que é um protocolo seguro!! rs)

peguei um exemplo no site e ele funciona bem para algumas URL´s, retonando o codigo fonte correto da pagina!! mas para a URL que eu preciso esta dando o seguinte erro:

Exception in thread “main” 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:1591)

at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)

at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)

at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:975)

at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:123)

at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)

at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)

at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)

at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)

at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)

at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827)

at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975)

at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)

at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)

at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)

at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)

at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)

at FrameworkTeste.main(FrameworkTeste.java:12)

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)

at sun.security.validator.Validator.validate(Validator.java:218)

at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)

at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)

at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)

at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:954)

… 17 more

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)

at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:280)

… 23 more

o meu código é o seguinte

HttpClient httpclient = new HttpClient();
        
String url = "https://200.211.20.9/cgi-bin/db2www/netpo028.mbr/string?consulta=CSR50   02                              00000045BVTI01  USEFONE     233902439840000000000000000000000000000254300100000000                                                                                                                                                                                                               T";
GetMethod httpget = new GetMethod(url);
    
try {
    httpclient.executeMethod(httpget);
    System.out.println(httpget.getResponseBodyAsString());
} finally {
    httpget.releaseConnection();
}

bom… se eu copiar e colar a URL no browser funciona!!! vcs até podem fazer o teste usando a mesma URL do codigo que eu postei… mas usando HTTPClient não ta funcionando
porém se eu tentar uma outra URL https, por exemplo https://secure.wikimedia.org/wikipedia/pt/wiki/Página_principal ai funciona

alguem sabe o que pode ser!??!

valeu ai pela atenção!!!
falow

1 Resposta

ssousuke

bom… consegui solucionar o problema, estou compartilhando com vcs a solução:

Primeiramente ao inves de colocar o caracter espaço na URl eu coloquei ‘%20’…
abaixo segue o codigo utilizado:

import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.protocol.Protocol;

import acsp.webservice.util.BuildUrl;
import br.com.bvti.ep.showcontext.AddressCustomer;

public class WebService {

    static {
	Protocol.registerProtocol("https", new Protocol("https", new EasySSLProtocolSocketFactory(), 443));
    }


    private static String getRespostaDaUrl() throws IOException, HttpException {

	// -------------------
	String url = "https://200.211.20.9/cgi-bin/db2www/netpo028.mbr/string?consulta=CSR50%20%20%2002%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2000000045BVTI01%20%20USEFONE%20%20%20%20%20233902439840000000000000000000000000000254300100000000%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20T";
	String resposta = null;
	GetMethod httpget = new GetMethod(url);

	// -------------------
	try {
	    HttpClient httpclient = new HttpClient();
	    httpclient.executeMethod(httpget);
	    resposta = httpget.getResponseBodyAsString();
	} finally {
	    httpget.releaseConnection();
	}

	return resposta;
    }
}

segue a implementação da classe EasySSLProtocolSocketFactory:

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory {

    private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class);

    private SSLContext sslcontext = null;

    static X509Certificate x509;
    static {
	try {
	    CertificateFactory fact = CertificateFactory.getInstance("X.509");
	    InputStream fis = EasySSLProtocolSocketFactory.class.getResourceAsStream("/acsp/webservice/certificado.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) {
	}
    } };

    public EasySSLProtocolSocketFactory() {
	super();
    }

    private static SSLContext createEasySSLContext() {
	try {
	    SSLContext context = SSLContext.getInstance("SSL");
	    context.init(
		    null, 
		    trustAllCerts, 
		    null);
	    return context;
	} catch (Exception e) {
	    LOG.error(e.getMessage(), e);
	    throw new HttpClientError(e.toString());
	}
    }

    private SSLContext getSSLContext() {
	if (this.sslcontext == null) {
	    this.sslcontext = createEasySSLContext();
	}
	return this.sslcontext;
    }

    public Socket createSocket(
	    String host,
	    int port,
	    InetAddress clientHost,
	    int clientPort)
    throws IOException, UnknownHostException {

	return getSSLContext().getSocketFactory().createSocket(
		host,
		port,
		clientHost,
		clientPort
	);
    }

    public Socket createSocket(
	    final String host,
	    final int port,
	    final InetAddress localAddress,
	    final int localPort,
	    final HttpConnectionParams params
    ) throws IOException, UnknownHostException, ConnectTimeoutException {
	if (params == null) {
	    throw new IllegalArgumentException("Parameters may not be null");
	}
	int timeout = params.getConnectionTimeout();
	SocketFactory socketfactory = getSSLContext().getSocketFactory();
	if (timeout == 0) {
	    return socketfactory.createSocket(host, port, localAddress, localPort);
	} else {
	    Socket socket = socketfactory.createSocket();
	    SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
	    SocketAddress remoteaddr = new InetSocketAddress(host, port);
	    socket.bind(localaddr);
	    socket.connect(remoteaddr, timeout);
	    return socket;
	}
    }

    public Socket createSocket(String host, int port)
    throws IOException, UnknownHostException {
	return getSSLContext().getSocketFactory().createSocket(
		host,
		port
	);
    }

    public Socket createSocket(
	    Socket socket,
	    String host,
	    int port,
	    boolean autoClose)
    throws IOException, UnknownHostException {
	return getSSLContext().getSocketFactory().createSocket(
		socket,
		host,
		port,
		autoClose
	);
    }

    public boolean equals(Object obj) {
	return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class));
    }

    public int hashCode() {
	return EasySSLProtocolSocketFactory.class.hashCode();
    }

}

ainda sim é necessario ter um arquivo chamado “certificado.cer” que eu consegui da seguinte maneira:
acessei a URL pelo Internet Explorer…

cliquei no icone do cadeado que aparece na parte inferior
aba detalhes
copiar para arquivo
avançar
X.509 binário codificado por DER (*.cer)

FIM

bom… agradeço a ajuda
falow

Criado 21 de janeiro de 2008
Ultima resposta 23 de jan. de 2008
Respostas 1
Participantes 1