Alex Rivera | Logout

Chrome closing connection on handshake with Java SSL Server

Asked 2011-09-23T21:40:09.433
11

There are several questions that are similar to this, but none address this specific issue. If there is one and I missed it, please direct me to the relevant solution.

Now for my issue. I wrote a test SSL Server in Java:

import java.io.FileInputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;

public class Server {
  public static void main(String[] args) throws Exception {
    KeyStore ks = KeyStore.getInstance("JKS");  
    ks.load(new FileInputStream("server.jks"), "123456".toCharArray());

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, "123456".toCharArray());

    SSLContext context = SSLContext.getInstance("TLS");
    context.init(kmf.getKeyManagers(), null, null);

    SSLServerSocketFactory factory = context.getServerSocketFactory();
    SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8443);

    SSLSocket socket = null;
    OutputStream out = null;

    while (true) {
      try {
        System.out.println("Trying to connect");
        socket = (SSLSocket) serverSocket.accept();
        socket.startHandshake();
        out = socket.getOutputStream();
        out.write("Hello World".getBytes());
        out.flush();
      } catch (SSLHandshakeException e) {
        e.printStackTrace();
        continue;
      } finally {
        if (socket != null) {
          socket.close();
        }
      }
    }
  }
}

And I created my key store like so:

keytool -genkey -keyalg RSA -alias server-keys -keystore server.jks

When prompted, I put localhost for the key name.

Then I compile (I am using Sun/Oracle JDK and JRE version 1.6.0_26):

javac Server.java
<
Edit
Report

1 Answer

6

WooHoo! I finally figured this one out. After long, frustrating hours of searching the Intarwebz, I found documentation on this hidden Java library in J2SE 6+.

com.sun.net.httpserver

This implementation simply negotiates the SSL handshake and returns the request as plain text:

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsExchange;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.util.concurrent.Executor;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;

public class HTTPS {
  public static void main(String[] args) throws Exception {
    KeyStore ks = KeyStore.getInstance("JKS");  
    ks.load(new FileInputStream("server.jks"), "123456".toCharArray());

    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, "123456".toCharArray());

    SSLContext context = SSLContext.getInstance("TLS");
    context.init(kmf.getKeyManagers(), null, null);

    final HttpsServer server = HttpsServer.create(new InetSocketAddress("localhost", 8443), 10);

    server.createContext("/", new HttpHandler() {
      public void handle(HttpExchange xchng) throws IOException {
        HttpsExchange exchange = (HttpsExchange) xchng;

        String ret = "";
        ret += exchange.getRequestMethod() + " " + exchange.getRequestURI() + " " + exchange.getProtocol() + "\n";

        Headers headers = exchange.getRequestHeaders();
        if (!headers.isEmpty()) {
          ret += "\n";
          for (String key : headers.keySet()) {
            ret += key + ": ";
            boolean semiColon = false
answered 2011-09-28T21:25:25.710

Your Answer