没有JKS的嵌入式码头上的TLS



我的目标:我正在进行Jetty Embedded的集成,使其易于使用。该接口将允许在不使用Java KeyStore的情况下集成TLS证书的外部源。

这将允许在构建分布式web服务(在我的案例中是一个实验性的自托管CDN)时具有更大的灵活性。

然而,我在构建集成时遇到了问题。存根实现在此存储库中。

我尝试过的:我曾尝试更换密钥管理器和信任管理器,并为其中的每个函数设置断点。但是,当尝试访问服务器时,这些断点永远不会被触发。相反,我遇到了这个错误:

javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:813)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:621)
at org.eclipse.jetty.server.HttpConnection.fillRequestBuffer(HttpConnection.java:322)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:231)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:261)
at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:150)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
at java.lang.Thread.run(Thread.java:748)

我曾尝试分析"标准"Jetty设置,即密钥库中的证书,但运气不佳。我找不到Jetty获取应该覆盖的密码/证书信息的位置。

我的问题:如何让Jetty使用我自己的证书源,而不是Java KeyStore和TrustStore?

@EJP为我指明了正确的方向,下面是如何做到这一点:

以下是需要如何做到这一点。

首先,为TLS设置码头:

HttpConfiguration https = new HttpConfiguration();
https.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new JettySslContextFactory(configuration.getSslProviders());
ServerConnector sslConnector = new ServerConnector(
server,
new SslConnectionFactory(sslContextFactory, "http/1.1"),
new HttpConnectionFactory(https)
);
sslConnector.setPort(httpsPort);

请注意类JettyslContextFactory。此类扩展了内置的X509ExtendedKeyManager,需要重写protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception方法才能提供自定义KeyManager,如下所示:

@Override
protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception {
return new KeyManager[] {
new JettyX509ExtendedKeyManager(certificateProviders)
};
}

除此之外,在每个连接中都会运行以下步骤:

  1. 向SNI匹配器咨询SNI主机名。这似乎是唯一一个可以使用SNI主机名的地方
  2. 咨询密钥管理器以获取特定密钥类型(EC或RSA)的别名(某种密钥ID)。在这里,我们需要从SNI匹配器中获取主机名,因为否则我们就不知道要匹配哪个主机名
  3. 根据别名(密钥ID),我们可以返回私钥和证书

至少这是我从调试这个问题中收集到的。完整的代码在这里在线。

相关内容

  • 没有找到相关文章

最新更新