Если вы хотите импортировать сертификат динамически, вам может потребоваться использовать пользовательский x509TrustManager
. Это делается при настройке SSLContext
, который сам по себе используется для создания SSLSocketFactory
или SSLEngine
.
jSSLutils - это библиотека, которая позволяет обернуть существующие диспетчеры доверия и настроить определенные параметры. Вам это не нужно, но это может помочь.
Это будет выглядеть следующим образом:
PKIXSSLContextFactory sslContextFactory = new PKIXSSLContextFactory();
sslContextFactory.setTrustManagerWrapper(new X509TrustManagerWrapper() {
@Override
public X509TrustManager wrapTrustManager(final X509TrustManager origManager) {
return new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return origManager.getAcceptedIssuers();
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
try {
// This will call the default trust manager
// which will throw an exception if it doesn't know the certificate
origManager.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
// If it throws an exception, check what this exception is
// the server certificate is in chain[0], you could
// implement a callback to the user to accept/refuse
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
origManager.checkClientTrusted(chain, authType);
}
};
}
});
SSLContext sslContext = sslContextFactory.buildSSLContext();
((PKIX)SSLContextFactory
и X509TrustManagerWrapper
взяты из jSSLutils, но остальное доступно с J2SE / J2EE.)
Есть несколько CertificateException
с , которые вы, возможно, захотите поймать (см. Подклассы).
Если вы сделаете обратный вызов для пользователя, возможно, что соединение SSL / TLS в первый раз не будет выполнено из-за истечения времени ожидания при рукопожатии SSL / TLS (если обратный вызов занимает слишком много времени для ответа.)
Затем вы можете использовать это SSLContext
в качестве значения по умолчанию, используя SSLContext.setSSLContext(...)
(из Java 6), но это не всегда хорошая идея. Если можете, передайте SSLContext
в библиотеку, которая устанавливает соединение SSL / TLS. Как это делается, может быть разным, но Apache HTTP Client 4.x, например, имеет несколько опций для настройки своих параметров SSL, один из которых - передача KeyStore
s, другой - передача SSLContext
.
.
Вы также можете использовать что-то для каждого потока, а не для каждого объекта, который будет подключаться (зависит от библиотеки), проверив текущий поток внутри X509TrustManager
: это, вероятно, усложнит ситуацию с точки зрения синхронизации и управления потоками / «осведомленность» от доверительного управляющего.