我需要为Java应用程序设置一个非常轻量级的HTTPS服务器.它是我们开发实验室中使用的模拟器,用于模拟野外设备接受的HTTPS连接.因为它纯粹是一个轻量级的开发工具,并且完全不以任何方式用于生产,所以我很乐意绕过认证和尽可能多的协商.
我打算HttpsServer
在Java 6 SE中使用这个类,但我很难让它运行起来.作为测试客户端我正在使用wget
cygwin命令行(wget https://[address]:[port]
)但wget
报告它"无法建立SSL连接".
如果我运行wget
与-d
进行调试选项,它告诉我"SSL握手失败".
我花了30分钟谷歌搜索这一切似乎只是指向描述方法的相当无用的Java6文档,但实际上并没有谈论如何让讨论或讨论提供任何示例代码.
任何人都可以朝着正确的方向推动我吗?
我最终使用的是:
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"); }
要生成密钥库:
$ keytool -genkeypair -keyalg RSA -alias self_signed -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.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(); } } }
创建自签名证书
keytool -genkeypair -keyalg RSA -alias selfsigned -keystore testkey.jks -storepass password -validity 360 -keysize 2048