Chrome closing connection on handshake with Java SSL Server

后端 未结 3 2020
攒了一身酷
攒了一身酷 2021-02-04 12:12

There are several questions that are similar to this, but none address this specific issue. If there is one and I missed it, please direct me to the relevant solution.

相关标签:
3条回答
  • 2021-02-04 12:27

    In my case there was a big hassle with supported ciphers and at the end it turned out that the order of them is important (the most desired by server on the very bottom - then the less wished above and so on...). You can figure out what is the wish list by checking https://www.ssllabs.com/ssltest Also you might have to patch your jdk with JCE (http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html) Although jdk 8 should have the latest ciphers included and enabled accourding to the documentation (https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider)

    private static final String TLS_PROTOCOL_1_2 = "TLSv1.2";
        private static final String TLS_PROTOCOL_1_1 = "TLSv1.1";
        private static final String TLS_PROTOCOL_3 = "SSLv3";
        private static final String TLS_RSA_WITH_AES_256_CBC_SHA ="TLS_RSA_WITH_AES_256_CBC_SHA";
        private static final String TLS_RSA_WITH_AES_256_CBC_SHA256 ="TLS_RSA_WITH_AES_256_CBC_SHA256";
        private static final String TLS_RSA_WITH_AES_256_GCM_SHA384 = "TLS_RSA_WITH_AES_256_GCM_SHA384";
        private static final String TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
        private static final String TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
        private static final String AUTHORIZATION = "Basic Zmlkb3I6d2lyIWJhbmsk";
    
        @Override
        public HttpURLConnection openSecureConnection(String path) throws IOException, KeyManagementException, NoSuchAlgorithmException {
            URL url = new URL(baseUrl+path);
            SSLContext sslContext = SSLContext.getInstance(TLS_PROTOCOL_1_2);
    
            TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                    }
            };
    
            sslContext.init(null, trustAllCerts, new  java.security.SecureRandom());
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
    
            con.setSSLSocketFactory(sslSocketFactory);
            con.setDoOutput(true);
            con.setConnectTimeout(getTimeout());
            con.setReadTimeout(getTimeout());
            //set server-prefered cipher suits
            SSLServerSocket soc = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
            soc.setEnabledProtocols(new String[]{TLS_PROTOCOL_3, TLS_PROTOCOL_1_2, TLS_PROTOCOL_1_1});
            soc.setEnabledCipherSuites(new String[] {
                    TLS_RSA_WITH_AES_256_CBC_SHA,
                    TLS_RSA_WITH_AES_256_CBC_SHA256,
                    TLS_RSA_WITH_AES_256_GCM_SHA384,
                    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
                    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
            });
    
            return con;
        }
    

    For jdk 1.7 is it important to add VM option "-Dhttps.protocols=TLSv1.1,TLSv1.2"

    0 讨论(0)
  • 2021-02-04 12:42

    WooHoo! I finally figured this one out. After long, frustrating hours of searching the Intarwebz, I found documentation on this hidden Java library in J2SE 6+.

    com.sun.net.httpserver

    This implementation simply negotiates the SSL handshake and returns the request as plain text:

    import com.sun.net.httpserver.Headers;
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    import com.sun.net.httpserver.HttpsConfigurator;
    import com.sun.net.httpserver.HttpsExchange;
    import com.sun.net.httpserver.HttpsParameters;
    import com.sun.net.httpserver.HttpsServer;
    
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetSocketAddress;
    import java.security.KeyStore;
    import java.util.concurrent.Executor;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    
    public class HTTPS {
      public static void main(String[] args) throws Exception {
        KeyStore ks = KeyStore.getInstance("JKS");  
        ks.load(new FileInputStream("server.jks"), "123456".toCharArray());
    
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, "123456".toCharArray());
    
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(kmf.getKeyManagers(), null, null);
    
        final HttpsServer server = HttpsServer.create(new InetSocketAddress("localhost", 8443), 10);
    
        server.createContext("/", new HttpHandler() {
          public void handle(HttpExchange xchng) throws IOException {
            HttpsExchange exchange = (HttpsExchange) xchng;
    
            String ret = "";
            ret += exchange.getRequestMethod() + " " + exchange.getRequestURI() + " " + exchange.getProtocol() + "\n";
    
            Headers headers = exchange.getRequestHeaders();
            if (!headers.isEmpty()) {
              ret += "\n";
              for (String key : headers.keySet()) {
                ret += key + ": ";
                boolean semiColon = false;
                for (String value : headers.get(key)) {
                  if (semiColon) {
                    ret += "; ";
                  }
    
                  ret += value;
                  semiColon = true;
                }
    
                ret += "\n";
              }
            }
    
            if (headers.get("Content-Length") != null) {
              InputStream in = exchange.getRequestBody();
              ret += "\n";
              int i;
              while ((i = in.read()) != -1) {
                ret += String.valueOf((char) i);
              }
            }
    
            headers = exchange.getResponseHeaders();
            headers.set("Content-Type", "text/plain");
    
            exchange.sendResponseHeaders(200, ret.length());
    
            OutputStream out = exchange.getResponseBody();
            out.write(ret.getBytes());
    
            exchange.close();
          }
        });
    
        server.setHttpsConfigurator(new HttpsConfigurator(context) {
          public void configure(HttpsParameters params) {
    
          }
        });
    
        server.setExecutor(new Executor() {
          public void execute(Runnable command) {
            new Thread(command).start();
          }
        });
    
        server.start();
    
        /*
         * In a real app:
         *
         * public class ServerShutdownHook extends Thread {
         *   HttpServer server;
         *   int        seconds;
         *
         *   public ServerShutdownHook(HttpServer server, int seconds) {
         *     this.server  = server;
         *     this.seconds = seconds;
         *   }
         *
         *   public void run() {
         *     System.out.println("Server shutting down.  Waiting " + this.seconds + " seconds for exchanges to complete.");
         *     server.stop(this.seconds);
         *   }
         * }
         *
         * Runtime.getRuntime().addShutdownHook(new ServerShutdownHook(server, 3));
         */
        Runtime.getRuntime().addShutdownHook(new Thread() {
          public void run() {
            System.out.println("Server shutting down.  Waiting 3 seconds for exchanges to complete.");
            server.stop(3);
          }
        });
      }
    }
    

    I tested this on my Ubuntu box and it works for the following browsers:

    • Chrome
    • Firefox
    • Opera
    • Mobile Safari (iPhone4)
    • Safari
    • IE
    0 讨论(0)
  • 2021-02-04 12:44

    I suspect there is a firewall in the way that dropped the connection for some reason, or an inbound or outbound proxy. You may need to sniff the network packet exchange.

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