我在 Java 11 / Jetty 11(也用 Java 17 测试)中尝试通过 HTTPS 实现 HTTP/2 时遇到异常。此代码在带有 Jetty 9 的 Java 8 中运行良好(除了在 Jetty 9 中是
SslContextFactory
而不是 SslContextFactory.Server
):
ServerConnector createSecureHttp2SocketConnector(Server server,String host,int port,SslStores sslStores,boolean trustForwardHeaders) {
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(sslStores.keystoreFile());
if (sslStores.keystorePassword() != null) {
sslContextFactory.setKeyStorePassword(sslStores.keystorePassword());
}
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
sslContextFactory.setUseCipherSuitesOrder(true);
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setSecureScheme("https");
httpConfiguration.addCustomizer(new SecureRequestCustomizer());
httpConfiguration.setSendServerVersion(false);
if(trustForwardHeaders) {
httpConfiguration.addCustomizer(new ForwardedRequestCustomizer());
}
HttpConnectionFactory http1 = new HttpConnectionFactory(httpConfiguration);
HTTP2ServerConnectionFactory http2 = new HTTP2ServerConnectionFactory(httpConfiguration);
NegotiatingServerConnectionFactory alpn = new ALPNServerConnectionFactory();
alpn.setDefaultProtocol(http2.getProtocol());
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
ServerConnector connector = new ServerConnector(server, ssl, alpn, http2, http1);
connector.setIdleTimeout(TimeUnit.HOURS.toMillis(1));
connector.setHost(host);
connector.setPort(port);
return connector;
}
迭代密码套件时会出现特定问题,在套件上:(或 NamedGroup.SECT163_K1)“TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384”和握手期间的协议“TLSv1.2”,位于
sun.security.ssl.HandshakeContext.isActivatable
:
for (CipherSuite suite : enabledCipherSuites) {
if (suite.isAvailble() && suite.supports(protocol)) {
if (isActivatable(suite, algorithmConstraints, cachedStatus)) {
protocols.add(protocol);
found = true;
break;
}
}
}
异常是:
unhandled field class ECField2m
由下一个代码引起
(NamedGroup
包含一个 NamedCurve
类型的字段,它实现了 AlgorithmParameterSpec
。该对象有一个 EllipticCurve
类型的字段,该属性 field
是导致异常的 ECField2m
类型):
班级:
org.conscrypt.OpenSSLECGroupContext
:
if (field instanceof ECFieldFp) {
p = ((ECFieldFp) field).getP();
} else {
throw new InvalidParameterException("unhandled field class "
+ field.getClass().getName());
}
被称为:
sun.security.ssl.NamedGroup
:
algParams = AlgorithmParameters.getInstance(namedGroupSpec.algorithm);
algParams.init(keAlgParamSpec);
其中
keAlgParamSpec
是NamedGroup.SECT163_K1
.
是否需要任何特定的配置更改才能使代码在 Java 11 / Jetty 11 中正常工作?
Java 8 和 Java 11 之间的默认 SSL/TLS 行为是否有任何变化可以解释这种差异?
我正在更新这个库以使用 Jetty 11 而不是 Jetty 9。您可以通过克隆该存储库并将分支更改为“release-5-j11
and running the test:
GenericSecureHttp2IntegrationTest”来测试此代码。