Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Java HTTPS server

I need to set up a really lightweight HTTPS server for a Java application. It's a simulator that's being used in our development labs to simulate the HTTPS connections accepted by a piece of equipment in the wild. Because it's purely a lightweight development tool and isn't used in production in any way at all, I'm quite happy to bypass certifications and as much negotiation as I can.

I'm planning on using the HttpsServer class in Java 6 SE but I'm struggling to get it working. As a test client, I'm using wget from the cygwin command line (wget https://[address]:[port]) but wget reports that it was "Unable to establish SSL connection".

If I run wget with the -d option for debugging it tells me "SSL handshake failed".

I've spent 30 minutes googling this and everything seems to just point back to the fairly useless Java 6 documentation that describes the methods but doesn't actually talk about how to get the darn thing talking or provide any example code at all.

Can anyone nudge me in the right direction?

like image 336
Andrew Avatar asked Feb 22 '10 02:02

Andrew


People also ask

How do I make my site HTTPS in Java?

If you are connecting to the standard SSL port, 443, you have the option of appending the port number to the URL string. However, if your Web server is using a nonstandard port for SSL traffic, you'll need to append the port number to your URL string like this: URL url = new URL("https://[your server]:7002");

Can you create an HTTPS Web server?

To create an HTTPS server, you need two things: an SSL certificate, and built-in https Node. js module. We need to start out with a word about SSL certificates. Speaking generally, there are two kinds of certificates: those signed by a 'Certificate Authority', or CA, and 'self-signed certificates'.


2 Answers

What I eventually used was this:

try {     // Set up the socket address     InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), config.getHttpsPort());      // Initialise the HTTPS server     HttpsServer httpsServer = HttpsServer.create(address, 0);     SSLContext sslContext = SSLContext.getInstance("TLS");      // Initialise the keystore     char[] password = "simulator".toCharArray();     KeyStore ks = KeyStore.getInstance("JKS");     FileInputStream fis = new FileInputStream("lig.keystore");     ks.load(fis, password);      // Set up the key manager factory     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");     kmf.init(ks, password);      // Set up the trust manager factory     TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");     tmf.init(ks);      // Set up the HTTPS context and parameters     sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);     httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext) {         public void configure(HttpsParameters params) {             try {                 // Initialise the SSL context                 SSLContext c = SSLContext.getDefault();                 SSLEngine engine = c.createSSLEngine();                 params.setNeedClientAuth(false);                 params.setCipherSuites(engine.getEnabledCipherSuites());                 params.setProtocols(engine.getEnabledProtocols());                  // Get the default parameters                 SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();                 params.setSSLParameters(defaultSSLParameters);             } catch (Exception ex) {                 ILogger log = new LoggerFactory().getLogger();                 log.exception(ex);                 log.error("Failed to create HTTPS port");             }         }     });     LigServer server = new LigServer(httpsServer);     joinableThreadList.add(server.getJoinableThread()); } catch (Exception exception) {     log.exception(exception);     log.error("Failed to create HTTPS server on port " + config.getHttpsPort() + " of localhost"); } 

To generate a keystore:

$ keytool -genkeypair -keyalg RSA -alias self_signed -keypass simulator \   -keystore lig.keystore -storepass simulator 

See also here.

Potentially storepass and keypass might be different, in which case the ks.load and kmf.init must use storepass and keypass, respectively.

like image 146
Andrew Avatar answered Sep 30 '22 01:09

Andrew


I updated your answer for a HTTPS server (not socket-based). It might help with CSRF and AJAX calls.

import java.io.*; import java.net.InetSocketAddress; import java.lang.*; import java.net.URL; import com.sun.net.httpserver.HttpsServer; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; import com.sun.net.httpserver.*; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters;  import java.io.InputStreamReader; import java.io.Reader; import java.net.URLConnection;  import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate;  import java.net.InetAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsExchange;  public class SimpleHTTPSServer {      public static class MyHandler implements HttpHandler {         @Override         public void handle(HttpExchange t) throws IOException {             String response = "This is the response";             HttpsExchange httpsExchange = (HttpsExchange) t;             t.getResponseHeaders().add("Access-Control-Allow-Origin", "*");             t.sendResponseHeaders(200, response.getBytes().length);             OutputStream os = t.getResponseBody();             os.write(response.getBytes());             os.close();         }     }      /**      * @param args      */     public static void main(String[] args) throws Exception {          try {             // setup the socket address             InetSocketAddress address = new InetSocketAddress(8000);              // initialise the HTTPS server             HttpsServer httpsServer = HttpsServer.create(address, 0);             SSLContext sslContext = SSLContext.getInstance("TLS");              // initialise the keystore             char[] password = "password".toCharArray();             KeyStore ks = KeyStore.getInstance("JKS");             FileInputStream fis = new FileInputStream("testkey.jks");             ks.load(fis, password);              // setup the key manager factory             KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");             kmf.init(ks, password);              // setup the trust manager factory             TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");             tmf.init(ks);              // setup the HTTPS context and parameters             sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);             httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext) {                 public void configure(HttpsParameters params) {                     try {                         // initialise the SSL context                         SSLContext context = getSSLContext();                         SSLEngine engine = context.createSSLEngine();                         params.setNeedClientAuth(false);                         params.setCipherSuites(engine.getEnabledCipherSuites());                         params.setProtocols(engine.getEnabledProtocols());                          // Set the SSL parameters                         SSLParameters sslParameters = context.getSupportedSSLParameters();                         params.setSSLParameters(sslParameters);                      } catch (Exception ex) {                         System.out.println("Failed to create HTTPS port");                     }                 }             });             httpsServer.createContext("/test", new MyHandler());             httpsServer.setExecutor(null); // creates a default executor             httpsServer.start();          } catch (Exception exception) {             System.out.println("Failed to create HTTPS server on port " + 8000 + " of localhost");             exception.printStackTrace();          }     }  } 

To create a self-signed certificate:

keytool -genkeypair -keyalg RSA -alias selfsigned -keystore testkey.jks -storepass password -validity 360 -keysize 2048 
like image 23
krishnakumar sekar Avatar answered Sep 30 '22 02:09

krishnakumar sekar