SSLHandshakeException при подключении к сайту HTTPS - PullRequest
0 голосов
/ 13 января 2020

Я создаю в Java HttpsURLConnection. Я скачал сертификаты с сайта и создал файл truststore.jks с этими сертификатами. Мое приложение получает сертификаты от truststore.jks и подключается к веб-сайту. И это работает ... на моем P C. Но после развертывания приложения на сервере я получил это ужасное исключение:

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)

Я создаю HttpsURLConnection в классе ConnectionFactory и запускаю метод connection.getInputStream ().

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. У вас есть идеи, где я ошибся? Помощь.

1 Ответ

0 голосов
/ 07 февраля 2020

Я понял это. Локально я подключен к сети моей компании и у меня есть их сертификаты (из-за прокси). Но сервер не использует прокси и должен иметь реальные сертификаты от сервера конечной точки.

...