Пример простого HTTPS соединения без проверки сертификата сервера
Далее коннекчусь к своему серверу программно. Для начала делаю такой код:
@Test
public void testSimpleHttpsClient()
    throws CertificateException, InterruptedException, UnrecoverableKeyException, NoSuchAlgorithmException,
           IOException, KeyManagementException, KeyStoreException {
    startServer(8080);
    URL url = new URL("https://localhost:8080/");
    HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
    con.setRequestMethod( "GET" );
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, null, null);
    con.setSSLSocketFactory(sslContext.getSocketFactory());
    int responseCode = con.getResponseCode();
    InputStream inputStream;
    if (responseCode == HttpURLConnection.HTTP_OK) {
        inputStream = con.getInputStream();
    } else {
        inputStream = con.getErrorStream();
    }
    // Process the response
    BufferedReader reader;
    String line = null;
    reader = new BufferedReader( new InputStreamReader( inputStream ) );
    while( ( line = reader.readLine() ) != null )
    {
        System.out.println( line );
    }
    inputStream.close();
}
Стартую сервер на 8080 порту, в метод startServer(int port) перенесен весь код, из предыдущего теста.
startServer(8080);
Указываю, что нужно создать HttpsUrlConnection на URL https://localhost:8080 методом GET.
URL url = new URL("https://localhost:8080/");
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setRequestMethod( "GET" );
Создаю «пустой» SSLContext и на его основе создаю SSLSocketFactory, который передаю в параметры соединению.
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
con.setSSLSocketFactory(sslContext.getSocketFactory());
Запускаю на тестирование, получаю исключение:
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:1764)
....
Ошибка говорит о том, что не найден сертификат, подтверждающий подлинность сервера. Правильно, я не указал TrustManager-ов. Соответственно сертификаты проверить нельзя. Добавляю пустой TrustManager, пока без сертификатов, разрешающий любые сертификаты.
TrustManager[] trustManagers = new TrustManager[] {
    new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {  }
        public void checkServerTrusted(X509Certificate[] certs, String authType) {  }
    }
};
Тестируюсь. Теперь «валидация» сертификата проходит, но получаю другое исключение:
java.io.IOException: HTTPS hostname wrong: should be
at sun.net.www.protocol.https.HttpsClient.checkURLSpoofing(HttpsClient.java:524)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:448)
Теперь сертификат сервера проверяется, но не проходит проверку имя хоста. Добавляю свой собственный HostnameVerifier:
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return s.equals(sslSession.getPeerHost());
}
};
con.setHostnameVerifier(hostnameVerifier);
Тестируюсь, соединение успешно. Результирующий код клиента и сервера, пока, такой:
import com.sun.net.httpserver.*;
import org.junit.Test;
import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class SimpleServerTest {
    static class MyHandler implements HttpHandler {
        public void handle(HttpExchange t) throws IOException {
          String response = "This is the response";
          t.sendResponseHeaders(200, response.length());
          OutputStream os = t.getResponseBody();
          os.write(response.getBytes());
        }
    }
    void startServer(int port) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException,
    UnrecoverableKeyException, InterruptedException, KeyManagementException{
		HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 5);
		server.createContext("/", new MyHandler());
		char[] storepass = "storepass".toCharArray();
		char[] keypass = "serverpass".toCharArray();
		KeyStore ks = KeyStore.getInstance("JKS");
		ks.load(SimpleServerTest.class.getResourceAsStream("server.jks"), storepass);
		KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
		kmf.init(ks, keypass);
		SSLContext sslContext = SSLContext.getInstance("TLS");
		sslContext.init(kmf.getKeyManagers(), new TrustManager[]{}, null);
		server.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
			public void configure (HttpsParameters params) {
			// get the remote address if needed
			InetSocketAddress remote = params.getClientAddress();
			SSLContext c = getSSLContext();
			// get the default parameters
			SSLParameters sslparams = c.getDefaultSSLParameters();
			params.setSSLParameters(sslparams);
			// statement above could throw IAE if any params invalid.
			// eg. if app has a UI and parameters supplied by a user.
			}
		});
    	server.setExecutor(null); // creates a default executor
    	server.start();
	}
    @Test
    public void testSimpleHttpsClientWithTrustManagerAndVerifier()
        throws CertificateException, InterruptedException, UnrecoverableKeyException, NoSuchAlgorithmException,
               IOException, KeyManagementException, KeyStoreException {
        startServer(8080);
        URL url = new URL("https://localhost:8080/");
        HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
        con.setRequestMethod( "GET" );
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManager[] trustManagers = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {  }
                public void checkServerTrusted(X509Certificate[] certs, String authType) {  }
            }
        };
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            public boolean verify(String s, SSLSession sslSession) {
                return s.equals(sslSession.getPeerHost());
            }
        };
        con.setHostnameVerifier(hostnameVerifier);
        sslContext.init(null, trustManagers, null);
        con.setSSLSocketFactory(sslContext.getSocketFactory());
        int responseCode = con.getResponseCode();
        InputStream inputStream;
        if (responseCode == HttpURLConnection.HTTP_OK) {
            inputStream = con.getInputStream();
        } else {
            inputStream = con.getErrorStream();
        }
        // Process the response
        BufferedReader reader;
        String line = null;
        reader = new BufferedReader( new InputStreamReader( inputStream ) );
        while( ( line = reader.readLine() ) != null )
        {
            System.out.println( line );
        }
        inputStream.close();
    }
}
Взято:
https://dev64.wordpress.com/2013/06/18/configure-embedded-jdk-http-server-for-https/