Java SSLSocket在一段时间后停止握手

时间:2017-12-02 14:56:37

标签: java sockets ssl

我遇到了一个奇怪的问题,我似乎无法找到导致这种情况发生的原因。当应用程序首先启动时,应用程序中的SSL套接字工作正常,但是在某个时间之后或者在一些加载之后,握手过程开始出现问题。当通过openssl命令测试时,它有时会在写入客户端问候后停留几秒钟,然后返回没有证书可用错误,或者有时会出现此错误

CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state

以下是如何创建SSLSocket并初始化密钥库的代码。

课程开始

public synchronized void start(CamdMessageListener listener, CaProfile profile) throws IOException, SocketException {
    this.profile = profile;
    if (srv == null) {
        try {
           createServerSocket();
        } catch (IOException e) {
        }
    }
    if (acceptThread == null && null != srv) {
        if (useSsl) {
            acceptThread = new AcceptSSLThread(listener, this);
        }
        else {
            acceptThread = new AcceptThread(listener, this);
        }
    }
    portNumbers.put(new Integer(port), this);
    acceptThread.start();
    alive = true;
}

创建服务器套接字

public void createServerSocket() throws IOException {
    synchronized (this) {
        if (this.useSsl) {
            ListenPort.logger.info("(ListenPort " + this.port + ") creating SSL server Socket , using Ssl : On");
            try {
                final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
                ListenPort.logger.info("ListenPort " + this.port + ") Default keymanagerFactory algorithm:  '" + KeyManagerFactory.getDefaultAlgorithm() + "'.");
                //final KeyManagerList keyManagers = new KeyManagerList();
                //final TrustManagerList trustManagers = new TrustManagerList();
                final ArrayList<KeyManager> keyManagers = new ArrayList<KeyManager>();
                final ArrayList<TrustManager> trustManagers = new ArrayList<TrustManager>();

                this.keystores.forEach((k, v) -> {
                    try {
                        ListenPort.logger.info("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "'");
                        final KeyStore ks = KeyStore.getInstance("JKS");
                        final KeyStore ks2 = KeyStore.getInstance("JKS");
                        final FileInputStream fis = new FileInputStream(k);
                        ListenPort.logger.info("(ListenPort " + this.port + ") Retrieving ssl ids from keystore '" + k + "' = passwd '" + v + "'");
                        ks2.load(fis, v.toCharArray());
                        ListenPort.logger.info("(ListenPort " + this.port + ")                         keystore '" + k + "' Loaded.");
                        final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                        final TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                        ListenPort.logger.info("(ListenPort " + this.port + ")          initializing Keymanager '" + k + "'.");
                        kmf.init(ks2, v.toCharArray());
                        final KeyManager[] km = kmf.getKeyManagers();
                        if (km.length > 0) {
                            ListenPort.logger.finest("(ListenPort " + this.port + ") Reading " + km.length + " key(s)");
                            for (int i = 0; i < km.length; ++i) {
                                ListenPort.logger.finest("(ListenPort " + this.port + ") Reading key " + km[i]);
                                keyManagers.add(km[i]);
                            }
                        }
                        ListenPort.logger.info("(ListenPort " + this.port + ")          initializing trustmanager '" + k + "'.");
                        tmf.init(ks2);
                        final TrustManager[] tm = tmf.getTrustManagers();
                        if (tm.length > 0) {
                            ListenPort.logger.finest("(ListenPort " + this.port + ") Reading " + km.length + " trust(s)");
                            for (int j = 0; j < tm.length; ++j) {
                                ListenPort.logger.finest("(ListenPort " + this.port + ")  Reading trust " + tm[j]);
                                trustManagers.add(tm[j]);
                            }
                        }
                        ListenPort.logger.info("(ListenPort " + this.port + ") Retrieving ssl On : from keystore '" + k + "' ok");
                    }
                    catch (UnrecoverableKeyException e7) {
                        ListenPort.logger.info("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "' unrecoverable Key");
                    }
                    catch (KeyStoreException e8) {
                        ListenPort.logger.info("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "' Bad Keystore");
                    }
                    catch (NoSuchAlgorithmException e9) {
                        ListenPort.logger.info("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "' No such Algorithm");
                    }
                    catch (CertificateException e10) {
                        ListenPort.logger.info("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "' Bad Certificate");
                    }
                    catch (IOException e11) {
                        ListenPort.logger.severe("(ListenPort " + this.port + ") ssl On : keystore ='" + k + "' IOExcept");
                    }
                    return;
                });
                try {
                    KeyManager[] km2 = new KeyManager[0];
                    TrustManager[] tp = new TrustManager[0];
                    km2 = keyManagers.toArray(km2);
                    tp = trustManagers.toArray(tp);
                    ListenPort.logger.finest("(ListenPort " + this.port + ") Init SSL Context : " + km2.length + " key , " + tp.length + " trusts");
                    sslContext.init(km2, tp, null);
                    SSLServerSocket sslsrv;
                    if (this.bindAddr == null) {
                        ListenPort.logger.finest("(ListenPort " + this.port + ") No specific Binding Address");
                        sslsrv = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(this.port);
                    }
                    else {
                        ListenPort.logger.finest("(ListenPort " + this.port + ") Binding Address" + this.bindAddr.getHostAddress());
                        sslsrv = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(this.port, 0, this.bindAddr);
                    }
                    ListenPort.logger.finest("(ListenPort " + this.port + ") Enabling protocols");
                    String[] protocols = sslsrv.getSupportedProtocols();
                    for (int l = 0; l < protocols.length; ++l) {
                        ListenPort.logger.finest("(ListenPort " + this.port + ")                 " + protocols[l]);
                    }
                    sslsrv.setEnabledProtocols(protocols);
                    String[] suites = sslsrv.getSupportedCipherSuites();
                    ListenPort.logger.finest("(ListenPort " + this.port + ") Supported cipher suites are:");
                    for (int m = 0; m < suites.length; ++m) {
                        ListenPort.logger.finest("(ListenPort " + this.port + ")            " + suites[m]);
                    }
                    sslsrv.setEnabledCipherSuites(suites);
                    suites = sslsrv.getEnabledCipherSuites();
                    ListenPort.logger.finest("(ListenPort " + this.port + ") Supported cipher suites are:");
                    for (int m = 0; m < suites.length; ++m) {
                        ListenPort.logger.finest("(ListenPort " + this.port + ")            " + suites[m]);
                    }
                    ListenPort.logger.finest("(ListenPort " + this.port + ") Support protocols are:");
                    protocols = sslsrv.getSupportedProtocols();
                    for (int m = 0; m < protocols.length; ++m) {
                        ListenPort.logger.finest("(ListenPort " + this.port + ")            " + protocols[m]);
                    }
                    this.srv = sslsrv;
                }
                catch (NullPointerException e) {
                    ListenPort.logger.warning("ListenPort " + this.port + ") Erreur Creating server socket : " + e.getMessage());
                }
                catch (IOException e2) {
                    ListenPort.logger.warning("ListenPort " + this.port + ") Erreur Creating server socket" + e2.getMessage());
                }
                ListenPort.logger.info("(ListenPort " + this.port + ") ssl On server created");
            }
            catch (NoSuchAlgorithmException e3) {
                if (null != this.srv) {
                    this.srv.close();
                }
                this.srv = null;
                System.err.println(" open ssl listenning port : no such algorithm");
                ListenPort.logger.severe("ListenPort " + this.port + ") open ssl listenning port : no such algorithm disabling ssl : " + e3.getMessage());
            }
            catch (KeyManagementException e4) {
                if (null != this.srv) {
                    this.srv.close();
                }
                this.srv = null;
                ListenPort.logger.severe("(ListenPort " + this.port + ") creating SSL server Socket :key management problem " + e4.getMessage());
            }
            catch (Exception e5) {
                if (null != this.srv) {
                    this.srv.close();
                }
                this.srv = null;
                ListenPort.logger.info("(ListenPort " + this.port + ") creating SSL server Socket :key  management problem " + e5.getMessage());
            }
            ListenPort.logger.info("(ListenPort " + this.port + ") creating server Socket , using Ssl : On");
        }
        else {
            srv = new ServerSocket();
            try {
                if (this.bindAddr == null) {
                    srv.bind(new InetSocketAddress(this.port));
                }
                else {
                    srv.bind(new InetSocketAddress(this.bindAddr, this.port));
                }
            }
            catch (BindException e6) {
            }
        }
    }
}

AcceptSSLThread

public void run()
{
    while (this.listenPort.isAlive()) {
      try
      {
        SSLSocket s = (SSLSocket)this.listenPort.getServerSocket().accept();

        SSLSession sess = s.getSession();
        this.logger.info("Peer host is " + sess.getPeerHost());
        this.logger.info("Cipher is " + sess.getCipherSuite());
        this.logger.info("Protocol is " + sess.getProtocol());
        this.logger.info("ID is " + sess.getId());
        this.logger.info("Session created in " + sess.getCreationTime());
        this.logger.info("Session accessed in " + sess.getLastAccessedTime());


        String ip = s.getInetAddress().getHostAddress();

        int maxThreads = ProxyConfig.getInstance().getMaxThreads();
        if (Thread.activeCount() > maxThreads) {
          try {
            Thread.sleep(1000L);
          } catch (InterruptedException localInterruptedException) {}
          this.logger.severe("Max-threads exceeded (" + maxThreads + "), closing incoming connection: " + CustomFormatter.formatAddress(ip));
          s.close();


        }
        else if ((!this.listenPort.isAllowed(ip)) || (this.listenPort.isDenied(ip))) {
          this.logger.fine("Rejected connection: " + CustomFormatter.formatAddress(ip) + " not allowed.");
          com.bowman.cardserv.session.SessionManager.getInstance().fireUserLoginFailed("?@" + ip, this.listenPort + "/", ip, "rejected by [" + this.listenPort + "] ip deny list.");
          s.close();
        } else {
          this.logger.fine("Accepted connection: " + CustomFormatter.formatAddress(ip));

          ProxySession ps;
          try
          {
            ps = createSession(s, this.listenPort, this.listener);
          } catch (UnknownHostException e) {
            this.logger.fine("Unknown Host Excpeption: " + CustomFormatter.formatAddress(ip) + " : " + e.getMessage() + "' cause: " + e.getCause().getMessage());
            ps = null;
          } catch (IOException e) {
            this.logger.fine("IOExcpeption: " + CustomFormatter.formatAddress(ip) + " : " + e.getMessage() + "' cause: " + e.getCause().getMessage());
            ps = null;
          }
          catch (Exception e) {
            this.logger.fine("Exception : " + CustomFormatter.formatAddress(ip) + " : " + e.getMessage() + "' cause: " + e.getCause().getMessage());
            ps = null;
          }
          if (ps == null) {
            try { s.close();
            }
            catch (Exception localException1) {}
          }
        }
      } catch (java.net.SocketException e) {
        this.logger.throwing("Server socket closed: " + this.listenPort + " (" + e.getMessage() + ")", e);
        this.listenPort.destroy();
      } catch (IOException e) {
        this.logger.severe("Exception accepting socket connection for [" + this.listenPort + "], aborting...", e);
        this.listenPort.destroy();
      } catch (Throwable t) {
        this.logger.severe("Error in accept loop: " + t, t);
        return;
      }
    }
}

问题有时会发生在几分钟之后,有时几个小时之后,也许用户负载与问题有关。但是当启动应用程序时它工作正常,并且如果配置文件发生更改,则有一个用于刷新套接字的系统,因此如果我更改配置文件并再次执行SSL代码,则它会再次开始工作并再次停止一段时间后。这真让我疯狂。

此处还有代码部分,如果配置更新,则刷新密钥库。

public void configUpdated(ProxyXmlConfig xml) throws ConfigException {
    int port = xml.getPortValue("listen-port");

    if (portNumbers.containsKey(new Integer(port))) {
        ListenPort lp = (ListenPort)portNumbers.get(new Integer(port));
        if (lp != this) {
            throw new ConfigException(xml.getFullName(), "listen-port", "Listen-port '" + port + "' already in use by [" + lp + "]");
        }
    }
    ProxyXmlConfig sslXml = null;
    try {
        sslXml = xml.getSubConfig("ssl");
    }
    catch (ConfigException e) {
        ListenPort.logger.info("(ListenPort " + port + ") " + e.getMessage());
    }
    catch (Exception e2) {
        ListenPort.logger.info("(ListenPort " + port + ") " + e2.getMessage());
    }

    if (sslXml != null && "true".equalsIgnoreCase(sslXml.getStringValue("enabled"))) {
        Iterator iter = sslXml.getMultipleSubConfigs("keystore");
        this.keystores.clear();
        if (iter != null) {
            while (iter.hasNext()) {
                ProxyXmlConfig keystore = (ProxyXmlConfig) iter.next();
                if (keystore.getName() != null && keystore.getName().length() > 0) {
                    String passwd = keystore.getStringValue("password");
                    String store = keystore.getContents();
                    if (new File(store).exists()) {
                        this.keystores.put(store, passwd);
                        ListenPort.logger.finest("(ListenPort " + port + ") loading from config file :'" + store + "' passwd '" + passwd + "'");
                    }
                    else {
                        ListenPort.logger.warning("(ListenPort " + port + ") +Keystore file " + keystore.getName() + "unreachable - ignoring ");
                    }
                }
            }
        }
        this.useSsl = true;
    }
    setPort(port);

    String bindIp = null; bindAddr = null;
    try {
        bindIp = xml.getStringValue("bind-ip");
    } catch (ConfigException ex) {}
    if(bindIp != null) try {
      bindAddr = InetAddress.getByName(bindIp);
    } catch (UnknownHostException e3) {
    ListenPort.logger.throwing("ListenPort " + port + ") Bind IP Exception '" + e3.getMessage() + "' for bindin " + bindIp, new ConfigException(xml.getFullName(), "bind-ip", "Invalid listen-port bind-ip: " + bindIp));
    } catch (Exception e4) {
    ListenPort.logger.throwing("ListenPort " + port + ") Bind IP Exception '" + e4.getMessage() + "' for bindin " + bindIp, new ConfigException(xml.getFullName(), "bind-ip", "Invalid listen-port bind-ip: " + bindIp));
    }

    properties.clear();
    Iterator iter2 = xml.getMultipleSubConfigs(null);
    if (iter2 != null) {
        ProxyXmlConfig e5; 
        while (iter2.hasNext()) {
            e5 = (ProxyXmlConfig)iter2.next();
            if (e5.getName() != null && e5.getName().length() > 0) {
                this.properties.put(e5.getName(), xml);
            }
        }

        try {
            e5 = (ProxyXmlConfig)properties.remove("allow-list");
            if (e5 == null) throw new ConfigException("");
            String allow = e5.getStringValue("allow-list");
            allowList = new HashSet(Arrays.asList(allow.split(" ")));
        } catch (ConfigException ce) {
          allowList = new HashSet();
        }
        try {
            e5 = (ProxyXmlConfig)properties.remove("deny-list");
            if (e5 == null) throw new ConfigException("");
            String deny = e5.getStringValue("deny-list");
            denyList = new HashSet(Arrays.asList(deny.split(" ")));
        } catch (ConfigException ce) {
          denyList = new HashSet();
        }

    }
}

非常感谢任何帮助,谢谢。

0 个答案:

没有答案