Conectar HTTPS na mão

Pessoal estou com um pequeno grande problema:

Preciso acessar uma url https no meu tomcat, mas fora do browser, configurei o server.xml, criei o .keystore e fiz uma classe para testar o acesso a essa url na mão.

Para conectar uma url normal(Http) funciona beleza, mas quando acesso a minha https, que funciona no navegador perfeitamente, (https://localhost:8443/) ele joga uma exception

Configuração do server.xml:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
      maxThreads="150" scheme="https" secure="true"
      clientAuth="false" sslProtocol="TLS" />

Classe de acesso:

package httpTest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class HttpTest {
	public static void main(String[] args) {
		try {
			URL url = new URL("https://localhost:8443/");
			HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
			
			con.connect();
			
			String linha = "";
			StringBuffer buffer = new StringBuffer();
			
			BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
			while ((linha = br.readLine())!= null){
				buffer.append(linha + "\n");
			}
			System.out.println(buffer.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

E a exception:

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:1520)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:182)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:176)
	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:511)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:449)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:817)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1029)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1056)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1040)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
	at httpTest.HttpTest.main(HttpTest.java:20)
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)
	... 11 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)
	... 17 more

Valeu!! :thumbup:

Bom, consegui resolver este problema, vou postar aqui a solução para caso alguém tenha o mesmo, já consiga solucionar.

Apenas uma observação:
Esta é uma solução não muito segura pois faz com que o programa cliente aceite qualquer certificado, mas no meu caso que a url vai ser fixa dentro do software, é logico que não precisaria de certificação.
Caso seu software necessite a validação da certificação, não utilize isto.

Depois de apanhar um pouco consegui fazer isto:

Esta classe serve para aprovar todo o certificado de segurança que chega à conexão

package httpTest;

import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class MyTrustManager implements X509TrustManager {

	public MyTrustManager(KeyStore arg1) {

	}

	public void checkClientTrusted(X509Certificate[] arg0, String arg1)	throws CertificateException {
		System.out.println("checkClientTrusted");
	}

	public void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {
		System.out.println("checkServerTrusted");
	}

	public X509Certificate[] getAcceptedIssuers() {
		return null;
	}

}

Já a classe main ficou assim:

package httpTest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;

public class HttpTest {

	/**
	 * @param args
	 */
	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		TrustManager[] trms = new TrustManager[]{new MyTrustManager(null)};
		SSLContext ssl;
		
		try{
			ssl = SSLContext.getInstance("TLS");
			ssl.init(null, trms, null);
			SSLContext.setDefault(ssl);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		}
		
		try {
		
			URL url = new URL("https://localhost:8443/");
			HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
			
			con.setHostnameVerifier(new javax.net.ssl.HostnameVerifier(){
				public boolean verify(String arg0, SSLSession arg1) {
					return true;
				}
			});
			
			con.connect();
			
			String linha = "";
			StringBuffer buffer = new StringBuffer();
			
			BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
			while ((linha = br.readLine())!= null){
				buffer.append(linha + "\n");
			}
			System.out.println(buffer.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

E era isso, espero que ajude quem vai passar por isso um dia!!!

:thumbup: