Simple Java HTTPS server

j'ai besoin de configurer un serveur HTTPS vraiment léger pour une application Java. C'est un simulateur qui est utilisé dans nos laboratoires de développement pour simuler les connexions HTTPS acceptées par un équipement dans la nature. Parce qu'il s'agit d'un outil de développement purement léger et qu'il n'est utilisé en aucune façon dans la production, je suis très heureux de contourner les certifications et autant de négociation que je peux.

j'ai l'intention d'utiliser le HttpsServer cours en Java 6 SE mais j'ai du mal à l'obtenir travailler. En tant que client test j'utilise wget à partir de cygwin ligne de commande (wget https://[address]:[port]), mais wget rapports qu'il était "incapable d'établir une connexion SSL".

si je cours wget-d option de débogage qui me dit "échec de la poignée de main SSL".

j'ai passé 30 minutes à googler ceci et tout semble juste renvoyer à la documentation Java6 assez inutile qui décrit les méthodes, mais ne parle pas réellement de la façon de faire parler la chose maudite ou fournir un exemple de code.

quelqu'un Peut-il me pousser dans la bonne direction?

35
demandé sur Raphael Ahrens 2010-02-22 05:31:36

3 réponses

ce que j'ai finalement utilisé était ceci:

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" );
}

Pour générer un fichier de clés:

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

Voir aussi ici.

potentiellement storepass et keypass peuvent être différents, auquel cas le ks.load et kmf.init doit utiliser storepass et keypass, respectivement.

39
répondu Andrew 2014-09-03 17:20:16

j'ai mis à jour votre réponse pour un serveur https(pas basé sur socket),il pourrait aider avec CSRF et AJAX appel

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();

        }
    }

}

Pour créer un certificat auto-signé

keytool -genkey -keyalg RSA -alias selfsigned -keystore testkey.jks -storepass password -validity 360 -keysize 2048
10
répondu krishnakumar sekar 2015-12-27 18:56:12

Juste un rappel pour les autres: com.sun.net.httpserver.HttpsServer dans les solutions ci-dessus ne fait pas partie de la norme Java, mais est propriétaire et livré seulement avec le Sun/Oracle JVM, de sorte que cela ne fonctionnera pas sur D'autres Java runtime.

il existe plusieurs serveurs HTTP légers que vous pouvez intégrer à votre application qui prennent en charge HTTPS et qui fonctionnent sur N'importe quelle JVM.

l'Un d'eux est JLHTTP-the Java Lightweight HTTP Server qui est un petit serveur un fichier (ou ~50K / 35K jar) sans dépendances. Mise en place du keystore, SSLContext, etc. est similaire à ce qui précède, car il repose également sur l'implémentation standard de JSSE, ou vous pouvez spécifier les propriétés du système standard pour configurer SSL. Vous pouvez voir le FAQ ou le code et sa documentation pour plus de détails.

1
répondu amichair 2018-06-04 12:15:23