首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >扩展server_name (SNI扩展)不使用jdk1.8.0发送,而使用jdk1.7.0发送

扩展server_name (SNI扩展)不使用jdk1.8.0发送,而使用jdk1.7.0发送
EN

Stack Overflow用户
提问于 2015-06-13 19:03:58
回答 4查看 23.1K关注 0票数 23

我已经使用ApacheCXF (v3.0.4)实现了一个JAX-WS客户端,一切都正常工作,但是当我想通过Java8 (jdk1.8.0_25)使用安全连接(SSL/TLS)时,问题就来了。

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

代码语言:javascript
复制
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

经过非对等分析后,我观察到这个问题是因为在Java8中没有发送server_name (SNI),但是在Java7中发送了它,并且web服务调用成功。

Java8日志(-Djavax.net.debug=all):缺少"Extension server_name“

代码语言:javascript
复制
[...]
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
***
[...]

Java7日志(-Djavax.net.debug=all) (Works):设置了 "Extension server_name“

代码语言:javascript
复制
[...]
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]
***
[...]

可以观察到,在Java7中设置了扩展server_name,server_name: host_name: testeo.hostname.es,然后web服务调用成功。

为什么Java8没有像Java7那样设置server_name?这是Java配置问题吗?

EN

回答 4

Stack Overflow用户

发布于 2015-12-16 01:53:43

正如前面提到的,原因与使用setHostnameVerifier()破坏SNI (扩展server_name)的JDK有关。https://bugs.openjdk.java.net/browse/JDK-8144566

我们的解决办法:经过测试,我们发现将连接的SSLSocketFactory设置为任何默认值似乎都能解决问题。

这不起作用: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());

我们的SSLSocketFactory外观:(请注意,它实际上什么也不做)

代码语言:javascript
复制
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);
    }
}
票数 15
EN

Stack Overflow用户

发布于 2017-09-13 22:44:40

请使用已修复此问题的JDK版本8u141及更高版本。有关更多详细信息,请查看 JDK 8u141 Bugs Fixes页面

票数 10
EN

Stack Overflow用户

发布于 2015-08-07 18:43:31

您或底层库( WS库可以做到这一点)可能正在使用setHostnameVerifier(..)

java8中有一个错误,如果setHostnameVerifier(..)SNI不是从客户端完成的。

https://bugs.openjdk.java.net/browse/JDK-8072464

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30817934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档