连接到 HTTPS 站点时出现 SSLHandshakeException
SSLHandshakeException while connecting to HTTPS site
我正在 Java HttpsURLConnection 中创建。我从网站上下载了证书并使用该证书创建了文件 truststore.jks。我的应用程序正在从 truststore.jks 获取证书并连接到网站。它可以工作……在我的电脑上。但是在服务器上部署应用程序后,我得到了这个丑陋的异常:
Cause: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Stack trace:
[sun.security.ssl.Alerts.getSSLException(Unknown Source)
sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
sun.security.ssl.Handshaker.processLoop(Unknown Source)
sun.security.ssl.Handshaker.process_record(Unknown Source)
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
我正在 ConnectionFactory class 和 运行 connection.getInputStream() 方法中创建 HttpsURLConnection。
ConnectionFactory.java:
public final class ConnectionFactory {
public HttpsURLConnection getHttpsURLConnection(URL url, String trustStorePath, String trustStorePassword)
throws FileTransferWorkerException {
KeyStore keyStore = loadKeyStore(trustStorePath, trustStorePassword);
TrustManagerFactory trustManagerFactory = initTrustManagerFactory(keyStore);
SSLSocketFactory sslSocketFactory = buildSSLSocketFactory(trustManagerFactory);
return buildConnection(url, sslSocketFactory);
}
private KeyStore loadKeyStore(String path, String password) throws FileTransferWorkerException {
KeyStore keystore;
try {
keystore = KeyStore.getInstance("JKS");
} catch (KeyStoreException e) {
throw new FileTransferWorkerException(e);
}
try (FileInputStream fileInputStream = new FileInputStream(path)) {
keystore.load(fileInputStream, password.toCharArray());
} catch (IOException | CertificateException | NoSuchAlgorithmException e) {
throw new FileTransferWorkerException("Can not load keyStore from " + path, e);
}
return keystore;
}
private TrustManagerFactory initTrustManagerFactory(KeyStore keyStore) throws FileTransferWorkerException {
TrustManagerFactory trustManagerFactory;
try {
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
} catch (NoSuchAlgorithmException e) {
throw new FileTransferWorkerException(e);
}
try {
trustManagerFactory.init(keyStore);
} catch (KeyStoreException e) {
throw new FileTransferWorkerException(e);
}
return trustManagerFactory;
}
private SSLSocketFactory buildSSLSocketFactory(TrustManagerFactory trustManagerFactory) throws FileTransferWorkerException {
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
throw new FileTransferWorkerException(e);
}
try {
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
} catch (KeyManagementException e) {
throw new FileTransferWorkerException(e);
}
return sslContext.getSocketFactory();
}
private HttpsURLConnection buildConnection(URL url, SSLSocketFactory sslSocketFactory) throws FileTransferWorkerException {
HttpsURLConnection connection;
try {
connection = (HttpsURLConnection) url.openConnection();
} catch (IOException e) {
throw new FileTransferWorkerException("Can not connect to " + url.getPath(), e);
}
connection.setSSLSocketFactory(sslSocketFactory);
return connection;
}
}
并调用方法:
private void download(URL url, String trustStorePath, String trustStorePassword, File file)
throws IOException, FileTransferWorkerException {
HttpsURLConnection connection = new ConnectionFactory().getHttpsURLConnection(url, trustStorePath, trustStorePassword);
try (ReadableByteChannel reader = Channels.newChannel(connection.getInputStream()){
...
} finally {
connection.disconnect();
}
}
我需要使用我的 truststor.jks 文件,而不是 cacerts。你知道我哪里出错了吗?帮助。
我想通了。在本地,我连接到我公司的网络并且我有他们的证书(因为代理)。但是服务器没有使用代理,应该有来自端点服务器的真实证书。
我正在 Java HttpsURLConnection 中创建。我从网站上下载了证书并使用该证书创建了文件 truststore.jks。我的应用程序正在从 truststore.jks 获取证书并连接到网站。它可以工作……在我的电脑上。但是在服务器上部署应用程序后,我得到了这个丑陋的异常:
Cause: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Stack trace:
[sun.security.ssl.Alerts.getSSLException(Unknown Source)
sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
sun.security.ssl.Handshaker.processLoop(Unknown Source)
sun.security.ssl.Handshaker.process_record(Unknown Source)
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
我正在 ConnectionFactory class 和 运行 connection.getInputStream() 方法中创建 HttpsURLConnection。
ConnectionFactory.java:
public final class ConnectionFactory {
public HttpsURLConnection getHttpsURLConnection(URL url, String trustStorePath, String trustStorePassword)
throws FileTransferWorkerException {
KeyStore keyStore = loadKeyStore(trustStorePath, trustStorePassword);
TrustManagerFactory trustManagerFactory = initTrustManagerFactory(keyStore);
SSLSocketFactory sslSocketFactory = buildSSLSocketFactory(trustManagerFactory);
return buildConnection(url, sslSocketFactory);
}
private KeyStore loadKeyStore(String path, String password) throws FileTransferWorkerException {
KeyStore keystore;
try {
keystore = KeyStore.getInstance("JKS");
} catch (KeyStoreException e) {
throw new FileTransferWorkerException(e);
}
try (FileInputStream fileInputStream = new FileInputStream(path)) {
keystore.load(fileInputStream, password.toCharArray());
} catch (IOException | CertificateException | NoSuchAlgorithmException e) {
throw new FileTransferWorkerException("Can not load keyStore from " + path, e);
}
return keystore;
}
private TrustManagerFactory initTrustManagerFactory(KeyStore keyStore) throws FileTransferWorkerException {
TrustManagerFactory trustManagerFactory;
try {
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
} catch (NoSuchAlgorithmException e) {
throw new FileTransferWorkerException(e);
}
try {
trustManagerFactory.init(keyStore);
} catch (KeyStoreException e) {
throw new FileTransferWorkerException(e);
}
return trustManagerFactory;
}
private SSLSocketFactory buildSSLSocketFactory(TrustManagerFactory trustManagerFactory) throws FileTransferWorkerException {
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
throw new FileTransferWorkerException(e);
}
try {
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
} catch (KeyManagementException e) {
throw new FileTransferWorkerException(e);
}
return sslContext.getSocketFactory();
}
private HttpsURLConnection buildConnection(URL url, SSLSocketFactory sslSocketFactory) throws FileTransferWorkerException {
HttpsURLConnection connection;
try {
connection = (HttpsURLConnection) url.openConnection();
} catch (IOException e) {
throw new FileTransferWorkerException("Can not connect to " + url.getPath(), e);
}
connection.setSSLSocketFactory(sslSocketFactory);
return connection;
}
}
并调用方法:
private void download(URL url, String trustStorePath, String trustStorePassword, File file)
throws IOException, FileTransferWorkerException {
HttpsURLConnection connection = new ConnectionFactory().getHttpsURLConnection(url, trustStorePath, trustStorePassword);
try (ReadableByteChannel reader = Channels.newChannel(connection.getInputStream()){
...
} finally {
connection.disconnect();
}
}
我需要使用我的 truststor.jks 文件,而不是 cacerts。你知道我哪里出错了吗?帮助。
我想通了。在本地,我连接到我公司的网络并且我有他们的证书(因为代理)。但是服务器没有使用代理,应该有来自端点服务器的真实证书。