Как заставить клиента Restlet игнорировать проблемы SSL-сертификата - PullRequest
6 голосов
/ 25 января 2012

В настоящее время я работаю в тестовой среде, где на сервере установлен самозаверяющий SSL-сертификат по умолчанию. Я использую Restlet 2.1-RC2 и создаю экземпляр клиентского ресурса так:

Client client = new Client(new Context(), Protocol.HTTP);
cr = new ClientResource(String.format(itql_endpoint,riQuery));
cr.setNext(client);

и повторное использование клиента для каждого звонка. Как настроить клиент так, чтобы он игнорировал проблемные сертификаты.

Ответы [ 2 ]

9 голосов
/ 25 января 2012

Правильный способ - импортировать этот самозаверяющий сертификат в доверенное хранилище клиента, используя keytool, например:

keytool -import -file server-cert.pem -alias myserver -keystore mytruststore.jks

Вы можете сделать это непосредственно в хранилище доверенных сертификатов JRE (lib/security/cacerts), в котором может отсутствовать некоторая гибкость, или сделать это в своей собственной копии этого файла, которую затем установите в хранилище доверенных сертификатов (пароль по умолчанию: changeit или changeme в OSX). Это хранилище доверенных сертификатов настраивается глобально для вашего приложения, используя обычные системные свойства javax.net.ssl.trustStore* (например, системное свойство -Djavax.net.ssl.trustStore=mytruststore-Djavax.net.ssl.trustStorePassword), или вы можете настроить его для определенного соединителя в Restlet, используя параметры контекста сервера, например:

Series<Parameter> parameters = client.getContext().getParameters();
parameters.add("truststorePath", "/path/to/your/truststore.jks");
// parameters.add("truststorePassword", "password");
// parameters.add("trustPassword", "password");
// parameters.add("truststoreType", "JKS");

Неправильный способ заключается в использовании TrustManager, который отключит любую проверку и передаст ее через SslContextFactory (в расширении SSL). Что-то в этом роде.

TrustManager tm = new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain,
                    String authType)
                    throws CertificateException {
    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }

    public void checkServerTrusted(X509Certificate[] chain,
                    String authType)
                    throws CertificateException {
        // This will never throw an exception.
        // This doesn't check anything at all: it's insecure.
    }
};

final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] {tm}, null);
Context context = client.getContext();
context.getAttributes().put("sslContextFactory", new SslContextFactory() {
    public void init(Series<Parameter> parameters) { }
    public SSLContext createSslContext() { return sslContext; }
});

Хотя первый метод может показаться немного более утомительным, чем второй (поскольку сначала нужно получить сертификат сервера и скопировать файлы), второй просто уберет сообщения об ошибках, ничего не проверяя о сертификате сервера. тем самым делая его уязвимым для активных атак MITM. Это будет применяться к любому соединению, для которого настроен SSLContext. (Этот «неправильный путь не является неправильным, потому что он использует пользовательский SSLContext, он неправильный из-за этой конкретной конфигурации SSLContext.)

1 голос
/ 01 июля 2013
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
      public boolean verify(String hostname, SSLSession session) {
        return true;
      }
    };
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
...