使用这个简单的 https 服务器,稍微修改一下以将 var 替换为 Java 8 兼容类型,我可以这样运行它:
$ java8 -cp . -Djavax.net.debug=ssl,keygen javatester.SimpleHTTPSServer | grep Nonce -C 5
SESSION KEYGEN:
PreMaster Secret:
0000: A7 7C E0 10 EB E5 7C 16 CF 70 65 30 04 AE 5B BC .........pe0..[.
0010: 6F 61 52 6C FC 71 58 D9 F4 BD 10 70 69 10 62 2A oaRl.qX....pi.b*
CONNECTION KEYGEN:
Client Nonce:
0000: A3 E4 45 27 77 6C 0D 5E BD F1 4E 9D 1E 2E …Run Code Online (Sandbox Code Playgroud) 阅读完以下内容后,我仍然坚持制作最低限度的https ://localhost 独立免安装 Web 服务器 Java 应用程序。它需要是无库的,使用 Java 8,并接受来自浏览器的连接,而无需先安装任何特殊的客户端证书。我不清楚自签名证书是否可以实现这一点,因为它只适用于“localhost”。
到目前为止,我已经使用生成了一些关键文件
openssl genrsa -aes128 -out privkey.pem 2048 # makes privkey.pem
openssl req -new -x509 -key privkey.pem # makes cert.crt
Run Code Online (Sandbox Code Playgroud)
我已经拼凑了最基本的 Kotlin 设置函数
private fun ssl():SSLServerSocketFactory {
val password = "MYPASSWORD".toCharArray()
val kmf = KeyManagerFactory.getInstance("SunX509")
val tmf = TrustManagerFactory.getInstance("SunX509")
val sslContext = SSLContext.getInstance("TLS")
// initialise the keystore
KeyStore.getInstance("JKS").let { ks->
FileInputStream("lig.keystore").use {
ks.load(it, password)
}
kmf.init(ks, password)
tmf.init(ks)
}
// …Run Code Online (Sandbox Code Playgroud) 我围绕 Java 的HttpsServer.
我安装了HttpHandler一个用短信回复请求的程序:
return exchange -> {
try {
OutputStream responseBodyStream = exchange.getResponseBody();
byte[] response = "Trouble with HTTPS and curl\n"
.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "text/plain");
exchange.sendResponseHeaders(200, response.length);
responseBodyStream.write(response);
responseBodyStream.close();
// Note that exchange.close() also closes the exchange's input stream
// and output stream
} catch (Exception e) {
log.warn("Could not handle request", e);
}
};
Run Code Online (Sandbox Code Playgroud)
当使用 curl 连接到服务器时,服务器响应,但 Java 进程继续使用整个核心,从而使服务器无响应。
正是这一行触发了这个问题:
responseBodyStream.close();
Run Code Online (Sandbox Code Playgroud)
如果我们删除该行,服务器将继续工作。
从文档:
为了正确终止每个交换,输出流必须关闭,即使没有发送响应正文。
我创建了一个项目来重现该问题。
到目前为止,我发现了一些潜在的线索:
com.sun.net.httpserver.HttpsServer我已经为 SOAP Web 服务开发了一个 Java 7 HTTPS 服务器(我使用)(主要受此 SO 答案的影响),区别在于该服务器设置为需要客户端身份验证。这是我使用的服务器配置代码:
final InetSocketAddress address = new InetSocketAddress( localhost, 8888 );
this.httpsServer = HttpsServer.create( address, 0 );
// ... KeyStore configuration ...
// configure the HTTPS server
this.httpsServer.setHttpsConfigurator( new HttpsConfigurator( sslContext )
{
@Override
public void configure(final HttpsParameters params)
{
try
{
// initialize the SSL context
final SSLContext c = SSLContext.getDefault();
final SSLEngine engine = c.createSSLEngine();
params.setNeedClientAuth( true );
params.setCipherSuites( engine.getEnabledCipherSuites() );
params.setProtocols( engine.getEnabledProtocols() );
// get the …Run Code Online (Sandbox Code Playgroud)