SSL handshake alert: unrecognized_name error since upgrade to Java 1.7.0

前端 未结 17 2770
栀梦
栀梦 2020-11-22 06:35

I upgraded from Java 1.6 to Java 1.7 today. Since then an error occur when I try to establish a connection to my webserver over SSL:

javax.net.ssl.SSLProtoco         


        
相关标签:
17条回答
  • 2020-11-22 06:57

    I hit the same problem and it turned out that reverse dns was not setup correct, it pointed to wrong hostname for the IP. After I correct reverse dns and restart httpd, the warning is gone. (if I don't correct reverse dns, adding ServerName did the trick for me as well)

    0 讨论(0)
  • 2020-11-22 06:57

    If you are building a client with Resttemplate, you can only set the endpoint like this: https://IP/path_to_service and set the requestFactory.
    With this solution you don't need to RESTART your TOMCAT or Apache:

    public static HttpComponentsClientHttpRequestFactory requestFactory(CloseableHttpClient httpClient) {
        TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        };
    
        SSLContext sslContext = null;
        try {
            sslContext = org.apache.http.ssl.SSLContexts.custom()
                    .loadTrustMaterial(null, acceptingTrustStrategy)
                    .build();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }   
    
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
    
        final SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,hostnameVerifier);
    
        final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", csf)
                .build();
    
        final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        cm.setMaxTotal(100);
        httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .setConnectionManager(cm)
                .build();
    
        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();
    
        requestFactory.setHttpClient(httpClient);
    
        return requestFactory;
    }
    
    0 讨论(0)
  • 2020-11-22 06:58

    My VirtualHost's ServerName was commented out by default. It worked after uncommenting.

    0 讨论(0)
  • 2020-11-22 07:00

    We also ran into this error on a new Apache server build.

    The fix in our case was to define a ServerAlias in the httpd.conf that corresponded to the host name that Java was trying to connect to. Our ServerName was set to the internal host name. Our SSL cert was using the external host name, but that was not sufficient to avoid the warning.

    To help debug, you can use this ssl command:

    openssl s_client -servername <hostname> -connect <hostname>:443 -state

    If there is a problem with that hostname, then it will print this message near the top of the output:

    SSL3 alert read: warning:unrecognized name

    I should also note that we did not get that error when using that command to connect to the internal host name, even though it did not match the SSL cert.

    0 讨论(0)
  • 2020-11-22 07:01

    It should be useful. To retry on a SNI error in Apache HttpClient 4.4 - the easiest way we came up with (see HTTPCLIENT-1522):

    public class SniHttpClientConnectionOperator extends DefaultHttpClientConnectionOperator {
    
        public SniHttpClientConnectionOperator(Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
            super(socketFactoryRegistry, null, null);
        }
    
        @Override
        public void connect(
                final ManagedHttpClientConnection conn,
                final HttpHost host,
                final InetSocketAddress localAddress,
                final int connectTimeout,
                final SocketConfig socketConfig,
                final HttpContext context) throws IOException {
            try {
                super.connect(conn, host, localAddress, connectTimeout, socketConfig, context);
            } catch (SSLProtocolException e) {
                Boolean enableSniValue = (Boolean) context.getAttribute(SniSSLSocketFactory.ENABLE_SNI);
                boolean enableSni = enableSniValue == null || enableSniValue;
                if (enableSni && e.getMessage() != null && e.getMessage().equals("handshake alert:  unrecognized_name")) {
                    TimesLoggers.httpworker.warn("Server received saw wrong SNI host, retrying without SNI");
                    context.setAttribute(SniSSLSocketFactory.ENABLE_SNI, false);
                    super.connect(conn, host, localAddress, connectTimeout, socketConfig, context);
                } else {
                    throw e;
                }
            }
        }
    }
    

    and

    public class SniSSLSocketFactory extends SSLConnectionSocketFactory {
    
        public static final String ENABLE_SNI = "__enable_sni__";
    
        /*
         * Implement any constructor you need for your particular application -
         * SSLConnectionSocketFactory has many variants
         */
        public SniSSLSocketFactory(final SSLContext sslContext, final HostnameVerifier verifier) {
            super(sslContext, verifier);
        }
    
        @Override
        public Socket createLayeredSocket(
                final Socket socket,
                final String target,
                final int port,
                final HttpContext context) throws IOException {
            Boolean enableSniValue = (Boolean) context.getAttribute(ENABLE_SNI);
            boolean enableSni = enableSniValue == null || enableSniValue;
            return super.createLayeredSocket(socket, enableSni ? target : "", port, context);
        }
    }
    

    and

    cm = new PoolingHttpClientConnectionManager(new SniHttpClientConnectionOperator(socketFactoryRegistry), null, -1, TimeUnit.MILLISECONDS);
    
    0 讨论(0)
  • 2020-11-22 07:01

    I have also come across this issue whilst upgrading from Java 1.6_29 to 1.7.

    Alarmingly, my customer has discovered a setting in the Java control panel which resolves this.

    In the Advanced Tab you can check 'Use SSL 2.0 compatible ClientHello format'.

    This seems to resolve the issue.

    We are using Java applets in an Internet Explorer browser.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题