Подтвердить что ты не робот

Почему я не могу найти доверительный центр для установления связи SSL?

Я использую Spring RESTTemplate на стороне клиента, чтобы звонить в конечную точку REST. Клиент в этом случае является приложением Spring, а Tomcat - контейнером сервлета.

У меня возникают проблемы с подключением к конечной точке HTTPS. Я получаю сообщение об ошибке, которое указывает, что он не может найти допустимый путь к доверенности. Где я могу это указать? Это делается на уровне контейнера или уровне конфигурации приложения (Spring)?

Трассировка стека:

org.springframework.web.client.ResourceAccessException: I/O error:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target;
nested exception is 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
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:330)
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:292)
org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:227)
4b9b3361

Ответ 1

Вам необходимо правильно настроить SSLContext, который делается внешним для RESTTemplate. Это должно начать:

    String keystoreType = "JKS";
    InputStream keystoreLocation = null;
    char [] keystorePassword = null;
    char [] keyPassword = null;

    KeyStore keystore = KeyStore.getInstance(keystoreType);
    keystore.load(keystoreLocation, keystorePassword);
    KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmfactory.init(keystore, keyPassword);

    InputStream truststoreLocation = null;
    char [] truststorePassword = null;
    String truststoreType = "JKS";

    KeyStore truststore = KeyStore.getInstance(truststoreType);
    truststore.load(truststoreLocation, truststorePassword);
    TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

    KeyManager [] keymanagers = kmfactory.getKeyManagers();
    TrustManager [] trustmanagers =  tmfactory.getTrustManagers();

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keymanagers, trustmanagers, new SecureRandom());
    SSLContext.setDefault(sslContext);

Ответ 2

Более конкретно, вызов этого метода сделает трюк, так что любые последующие вызовы HttpClient не будут заботиться о действительности сертификата SSL:

    public static void trustSelfSignedSSL() {
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        X509TrustManager tm = new X509TrustManager() {

            public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        ctx.init(null, new TrustManager[]{tm}, null);
        SSLContext.setDefault(ctx);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}