扩展 server_name(SNI 扩展)不是用 jdk1.8.0 发送而是用 jdk1.7.0 发送 [英] Extended server_name (SNI Extension) not sent with jdk1.8.0 but send with jdk1.7.0

查看:31
本文介绍了扩展 server_name(SNI 扩展)不是用 jdk1.8.0 发送而是用 jdk1.7.0 发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经通过使用 ApacheCXF (v3.0.4) 实现了一个 JAX-WS 客户端并且一切正常,但是当我想使用带有 java 8 (jdk1.8.0_25) 的安全连接 (SSL/TLS) 时问题就出现了.

I have implemented a JAX-WS client by using ApacheCXF (v3.0.4) and everything works successfully but the problem comes when I want to use a secure connection (SSL/TLS) with java 8 (jdk1.8.0_25).

我在日志中看到以下异常(-Djavax.net.debug=all):

I see the following exception in log (-Djavax.net.debug=all):

main, handling exception: java.net.SocketException: Connection reset
main, SEND TLSv1.2 ALERT:  fatal, description =    unexpected_message
main, WRITE: TLSv1.2 Alert, length = 2
main, Exception sending alert: java.net.SocketException: Connection reset by peer: socket write error

经过更深入的分析,我观察到问题的原因是在 Java 8 中没有发送 server_name (SNI),但是在 Java 7 中它被发送并且 Web 服务调用成功.

After a depeer analysis I have observed the problem is caused because the with Java 8 the server_name (SNI) is not sent but with Java 7 it is sent and the web service invocation works successfully.

Java 8 日志 (-Djavax.net.debug=all): 缺少扩展服务器名称"

Java 8 log (-Djavax.net.debug=all): Missing "Extension server_name"

[...]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
[...]

Java 7 日志 (-Djavax.net.debug=all)(有效):扩展服务器名称"已设置

Java 7 log (-Djavax.net.debug=all) (works): "Extension server_name" is set

[...]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
Extension server_name, server_name: [host_name: testeo.hostname.es]
***
[...]

据观察,在 Java 7 中,Extension server_name, server_name: [host_name: testeo.hostname.es] 已设置,然后 Web 服务调用成功运行.

It is observed that with Java 7 the Extension server_name, server_name: [host_name: testeo.hostname.es] is set and then the web service invocation works successfully.

为什么 Java 8 没有像 Java 7 那样设置 server_name?是 Java 配置问题吗?

Why didn't Java 8 set the server_name as Java 7 did? Is it a Java configuration issue?

推荐答案

如前所述,原因与使用 setHostnameVerifier() 破坏 SNI (Extension server_name) 的 JDK 错误有关.https://bugs.openjdk.java.net/browse/JDK-8144566

As mentioned, the cause is related to the JDK bug where using setHostnameVerifier() breaks SNI (Extension server_name). https://bugs.openjdk.java.net/browse/JDK-8144566

我们的解决方法:经过测试,我们发现将连接的 SSLSocketFactory 设置为默认值的任何内容似乎都可以解决问题.

Our workaround: After testing we found that setting a connection's SSLSocketFactory to just about anything from the default seems to fix the issue.

这不起作用:HttpsURLConnection.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());

这确实有效:HttpsURLConnection.setSSLSocketFactory(new SSLSocketFactoryFacade());

因此,要为 JAX-WS 客户端修复它,您可以执行以下操作:bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", new SSLSocketFactoryFacade());

So, to fix it for a JAX-WS client, you could do something like this: bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", new SSLSocketFactoryFacade());

我们的 SSLSocketFactory 门面:(注意它真的什么都不做)

Our SSLSocketFactory facade: (Note that it really doesn't do anything)

public class SSLSocketFactoryFacade extends SSLSocketFactory {

    SSLSocketFactory sslsf;

    public SSLSocketFactoryFacade() {
        sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return sslsf.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return sslsf.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
        return sslsf.createSocket(socket, s, i, b);
    }

    @Override
    public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
        return sslsf.createSocket(s, i);
    }

    @Override
    public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
        return sslsf.createSocket(s, i, inetAddress, i1);
    }

    @Override
    public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
        return createSocket(inetAddress, i);
    }

    @Override
    public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
        return createSocket(inetAddress, i, inetAddress1, i1);
    }
}

这篇关于扩展 server_name(SNI 扩展)不是用 jdk1.8.0 发送而是用 jdk1.7.0 发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆