java - Java 1.8.40 路径不与任何信任锚链接
问题描述
我Server Socket application
在 Java 1.8.40 上作为 Windows 服务运行了独立的 Java,我们有一个 Spring Web 应用程序作为客户端,它使用selfsigned SHA1 RSA 2048
证书执行 SSL 握手,Server Socket application
然后执行其他操作。我们在keystore.jks中确实有相同的selfsigned SHA1 RSA 2048
证书。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);
由于问题正在通过重新启动解决,因此只要在生产中发生此问题,我们就会重新启动。我们想避免这种情况并解决这个问题,有人可以帮我解决这个随机问题吗?
解决方案
推荐阅读
- vba - 如何在数据透视表合并中使用 R1C1 范围内的变量,excel 2010?
- haskell - 我可以根据某个类的可用性过滤类型级别列表吗?
- macos - MacOS 上的 Jenkins 从属 Java 路径
- android - 使用 Kotlin 的 RTL 布局菜单项的方向
- javascript - 从链接调用函数时出现 JS 引用错误
- c# - 当调色板 alpha 为零时,无法将单色 BMP 文件显示到图片框
- python - 如何改变 Alexa 的通话速度?
- sql - oracle在哪里存储撤消数据?在内存或硬盘中
- javascript - 触发选择以从 Vuejs 中的函数打开
- c# - 如何在 ASP .NET 的 configureServices 函数中获取连接字符串