У меня есть автономная Java Server Socket application
, работающая на Java 1.8.40 в качестве службы Windows, и у нас есть веб-приложение Spring в качестве клиента, которое выполняет рукопожатие SSL с сертификатом selfsigned SHA1 RSA 2048
с Server Socket application
, а затем выполняет другие действия.У нас есть тот же сертификат selfsigned SHA1 RSA 2048
в Server Socket application
keystore.jks.
Я вижу странную проблему с моим Server Socket application
в Production, случайным образом он выдает ниже исключения, а 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);
Поскольку проблема устраняется при перезапуске, мы выполняем перезапуск всякий раз, когда эта проблема возникает в Production.Мы хотим избежать этого и решить эту проблему. Может ли кто-нибудь попросить меня помочь решить эту случайную проблему?