Простой сервер JAVA HTTPS

мне нужно настроить действительно легкий HTTPS-сервер для приложения Java. Это симулятор, который используется в наших лабораториях разработки для имитации HTTPS-соединений, принятых частью оборудования в дикой природе. Поскольку это чисто легкий инструмент разработки и никоим образом не используется в производстве, я с удовольствием обойду сертификаты и столько переговоров, сколько смогу.

Я планирую использовать HttpsServer класс в Java 6 SE, но я изо всех сил пытаюсь его получить рабочий. В качестве тестового клиента я использую wget из командной строки cygwin (wget https://[address]:[port]), но wget сообщает, что"не удалось установить SSL-соединение".

если я запускаю wget С -d опция для отладки говорит мне, что "SSL-рукопожатие не удалось".

Я потратил 30 минут на это, и все, кажется, просто указывает на довольно бесполезную документацию Java6, которая описывает методы, но на самом деле не говорит о том, как заставить эту чертову вещь говорить или укажите любой пример кода вообще.

может кто-нибудь подтолкнуть меня в правильном направлении?

3 ответов


что я в конце концов использовал именно этот:

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

чтобы создать keystore:

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

см. также здесь.

потенциально storepass и keypass могут отличаться, в этом случае ks.load и kmf.init необходимо использовать storepass и keypass, соответственно.


я обновил ваш ответ для сервера https (не на основе сокета),это может помочь с CSRF и 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();

        }
    }

}

для создания самозаверяющего сертификата

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

просто напоминание другим: com.sun.net.httpserver.HttpsServer в решениях выше не является частью стандарта Java, но является собственностью и поставляется только с Sun/Oracle JVM, поэтому это не будет работать на любой другой среде выполнения Java.

есть несколько легких HTTP-серверов, которые вы можете встроить в свое приложение, поддерживающее HTTPS и работающее на любом JVM.

один из них -JLHTTP - Java легкий HTTP-сервер который является крошечным однофайловым сервером (или ~50K / 35K jar) без зависимостей. Настройка хранилища ключей, SSLContext и т. д. аналогично приведенному выше, поскольку он также полагается на стандартную реализацию JSSE, или вы можете указать стандартные системные свойства для настройки SSL. Вы можете увидеть часто задаваемые вопросы или код и документацию.

отказ от ответственности: я автор JLHTTP. Вы можете проверить его для себя и определить, соответствует ли он вашим потребностям. Надеюсь, вам это пригодится: -)