Servidor Java HTTPS simple

Necesito configurar un servidor HTTPS realmente liviano para una aplicación Java. Es un simulador que se utiliza en nuestros laboratorios de desarrollo para simular las conexiones HTTPS aceptadas por un equipo en la naturaleza. Debido a que es una herramienta de desarrollo ligera y no se utiliza en la producción de ninguna manera, estoy feliz de eludir las certificaciones y la mayor cantidad de negociación posible.

Estoy planeando usar la clase HttpsServer en Java 6 SE, pero estoy luchando para que funcione. Como cliente de prueba, estoy usando wget desde la línea de comando de cygwin ( wget https://[address]:[port] ) pero wget informa que fue “No se puede establecer una conexión SSL”.

Si ejecuto wget con la opción -d para la depuración, me dice “Falló el protocolo de enlace SSL”.

He pasado 30 minutos buscando en Google esto y todo parece indicar simplemente la inútil documentación de Java6 que describe los métodos pero que no habla de cómo hacer que el maldito sea el tema o proporcionar ningún código de ejemplo.

¿Alguien puede empujarme en la dirección correcta?

Lo que finalmente utilicé fue esto:

 try { // setup 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 ); // 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 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" ); } 

Para generar un keystore:

 $ keytool -genkey -alias alias -keypass simulator \ -keystore lig.keystore -storepass simulator 

Ver también aquí .

Potencialmente storepass y keypass pueden ser diferentes, en cuyo caso ks.load y kmf.init deben usar storepass y keypass, respectivamente.

Actualicé su respuesta para un servidor https (no basado en socket), podría ayudar con CSRF y AJAX Call

 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.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 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) { 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(); } } } 

Para crear un certificado autofirmado

 keytool -genkey -keyalg RSA -alias selfsigned -keystore testkey.jks -storepass password -validity 360 -keysize 2048 

Solo un recordatorio para los demás: com.sun.net.httpserver.HttpsServer en las soluciones anteriores no es parte del estándar Java, pero es propiedad exclusiva y se incluye solo con Sun / Oracle JVM, por lo que no funcionará en ningún otro tiempo de ejecución Java .

Existen varios servidores HTTP livianos que puede insertar en su aplicación que admitan HTTPS y se ejecuten en cualquier JVM.

Uno de ellos es JLHTTP: el servidor HTTP ligero de Java, que es un pequeño servidor de un solo archivo (o ~ jar de 50K / 35K) sin dependencias. La configuración del almacén de claves, SSLContext, etc. es similar a la anterior, ya que también se basa en la implementación estándar de JSSE, o puede especificar las propiedades estándar del sistema para configurar SSL. Puede ver las preguntas frecuentes o el código y su documentación para más detalles.

Descargo de responsabilidad: soy el autor de JLHTTP. Puede verificarlo usted mismo y determinar si se adapta a sus necesidades. Espero que le sea útil 🙂