javax.net.ssl.SSLHandshakeException: получено фатальное предупреждение: unknown_ca

Мне нужно подключиться к серверу через двойную аутентификацию SSL. Я добавил свой собственный закрытый ключ плюс сертификат в keystore.jks и самоподписанный сертификат сервера в truststore.jks, оба файла копируются в / usr / share / tomcat7. Фабрика сокетов, используемая моим кодом, предоставляется следующим провайдером:

@Singleton
public static class SecureSSLSocketFactoryProvider implements Provider<SSLSocketFactory> {
    private SSLSocketFactory sslSocketFactory;

    public SecureSSLSocketFactoryProvider() throws RuntimeException {
        try {
            final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            final InputStream trustStoreFile = new FileInputStream("/usr/share/tomcat7/truststore.jks");
            trustStore.load(trustStoreFile, "changeit".toCharArray());
            final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);

            final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            final InputStream keyStoreFile = new FileInputStream("/usr/share/tomcat7/keystore.jks");
            keyStore.load(keyStoreFile, "changeit".toCharArray());
            final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, "changeit".toCharArray());

            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

            this.sslSocketFactory = sslContext.getSocketFactory();

        } catch (final KeyStoreException e) {
            Log.error("Key store exception: {}", e.getMessage(), e);
        } catch (final CertificateException e) {
            Log.error("Certificate exception: {}", e.getMessage(), e);
        } catch (final UnrecoverableKeyException e) {
            Log.error("Unrecoverable key exception: {}", e.getMessage(), e);
        } catch (final NoSuchAlgorithmException e) {
            Log.error("No such algorithm exception: {}", e.getMessage(), e);
        } catch (final KeyManagementException e) {
            Log.error("Key management exception: {}", e.getMessage(), e);
        } catch (final IOException e) {
            Log.error("IO exception: {}", e.getMessage(), e);
        }
    }

    @Override
    public SSLSocketFactory get() {
        return sslSocketFactory;
    }
}

Когда я пытаюсь подключиться к конечной точке на сервере, я получаю следующее исключение:

javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.7.0_45]
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) ~[na:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) ~[na:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[na:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ~[na:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) ~[na:1.7.0_45]
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) ~[na:1.7.0_45]
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[na:1.7.0_45]
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) ~[na:1.7.0_45]

Есть идеи, что я здесь пропустил?


person Stine    schedule 10.03.2015    source источник
comment
Вы это решили? Как вы заставили сервер доверять вам, даже если он самоподписан? ...?   -  person venugopal    schedule 22.10.2016
comment
@venugopal Мне также интересно, каково было реальное решение этой проблемы (xkcd.com/979).   -  person George Pantazes    schedule 24.10.2018
comment
Мне удалось решить эту проблему, добавив useSSL=false в строку подключения   -  person matino    schedule 05.02.2019
comment
@matino не должно быть решением. Это недостаток безопасности.   -  person manuka_m    schedule 12.08.2019


Ответы (1)


Если вы получили предупреждение unknown_ca от сервера, значит серверу не понравился сертификат, который вы отправили в качестве сертификата клиента, потому что он не подписан центром сертификации, которому сервер доверяет сертификаты клиентов.

person Steffen Ullrich    schedule 10.03.2015
comment
@Steffen Ullrich, если серверу не нравится этот самоподписанный сертификат, как сделать его доверенным центром сертификации? - person venugopal; 22.10.2016
comment
Это также может произойти, если срок действия сертификата клиента истек, и сервер (правильно!) Проверяет действительность сертификата клиента. - person Christopher Schultz; 01.08.2018
comment
как я могу напечатать, какой это CA (тот, который считается неизвестным)? - person sysoutkoula; 15.11.2019