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?
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.
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
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.