Правильный способ - импортировать этот самозаверяющий сертификат в доверенное хранилище клиента, используя 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
.)