Java 1.8.40 Path不与任何信任锚链接

时间:2019-04-08 17:35:47

标签: java sockets ssl serversocket sslhandshakeexception

我有一个独立的Java Server Socket application作为Windows服务在Java 1.8.40上运行,我们有一个Spring Web应用程序作为Client,它使用selfsigned SHA1 RSA 2048证书和Server Socket application执行SSL握手,然后执行其他动作。我们在selfsigned SHA1 RSA 2048 keystore.jks中拥有相同的Server Socket application证书。

我在生产环境中看到Server Socket application出现了一个奇怪的问题,它随机抛出低于异常的异常,而Java客户端正在获得Peer not authenticated异常。如果我重新启动Server Socket application,则看不到以下异常,并且Java客户端可以成功执行SSL握手

com.ssltunnel.server.MainServerHandshakeThread | IO Error waiting for handshake
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ServerHandshaker.clientCertificate(Unknown Source)
at sun.security.ssl.ServerHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.ssltunnel.server.MainServerHandshakeThread.handshake(MainServerHandshakeThread.java:41)
at com.ssltunnel.server.MainServerHandshakeThread.run(MainServerHandshakeThread.java:71)
at com.ssltunnel.utilities.threading.ShutdownThreadPoolExecutor$1.run(ShutdownThreadPoolExecutor.java:37)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.validator.PKIXValidator.doValidate(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkClientTrusted(Unknown Source)
... 16 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.validate(Unknown Source)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(Unknown Source)
at java.security.cert.CertPathValidator.validate(Unknown Source)
... 22 more

下面是我的MainServerHandshakeThread

public class MainServerHandshakeThread implements Runnable {

    private final Socket clientSocket;
    private final MainServer server;
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MainServerHandshakeThread.class.getName());
    private boolean done;
    private static final long TIMEOUT= 10000000000L;
    public static final int NSTOMS = 1000000;

    public MainServerHandshakeThread(Socket clientSocket, MainServer server) {
        this.clientSocket = clientSocket;
        this.server = server;
    }

    private void handshake() throws IOException, InterruptedException, ClientNotFoundException {

        long start = System.nanoTime();
        // Changed to want to allow for diagnosing bad certificates
        ((SSLSocket) clientSocket).setNeedClientAuth(true);
        MainServerHandshakeHandler handshake = new MainServerHandshakeHandler();
        ((SSLSocket) clientSocket).addHandshakeCompletedListener(handshake);
        ((SSLSocket) clientSocket).startHandshake(); //Line# 41


        while (!handshake.isDone() && !done) {
            Thread.sleep(10);
            long duration = System.nanoTime() - start;
            if (duration>TIMEOUT) {
                done = true;
                LOG.warn("Handshake timeout");
            }
        }
        long stop = System.nanoTime();
        LOG.debug("Handshake done in ms: " + ((stop - start) / NSTOMS) );
        String serialNumber = handshake.getSerialNumber();
        LOG.debug(serialNumber);


    }

    @Override
    public void run() {
        try {
            handshake();
        } catch (IOException ex) {
            LOG.error("IO Error waiting for handshake", ex);
        } catch (InterruptedException ex) {
            LOG.error("Interrupted waiting for handshake", ex);
        } catch (ClientNotFoundException ex) {
            LOG.warn("Client not found",ex);
        } finally {
            LOG.debug("Handshake thread is done");
            done = true;
        }

    }

    @Override
    public void shutdown() {
        if (clientSocket!=null) {
            SocketUtils.closeQuietly(clientSocket);
        }
    }
}

我们确实在服务器套接字应用程序中配置了信任库和密钥库,如下所示:

    System.setProperty("javax.net.ssl.keyStore", "C:/server/conf/keystore.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", KEYSTOREPASS);
    System.setProperty("javax.net.ssl.trustStore", "C:/server/conf/keystore.jks");
    System.setProperty("javax.net.ssl.trustStorePassword", KEYSTOREPASS);

由于问题已通过重新启动解决,因此只要生产中发生此问题,我们都会重新启动。我们要避免这种情况并解决此问题,请有人帮我解决此随机问题吗?

0 个答案:

没有答案