Многие хосты страдают от различных проблем с SSL (самозаверяющий сертификат, нарушенная цепочка сертификатов) или просто корневой сертификат не находится в общесистемном списке доверенных центров сертификации.
До сих пор проблема была «решена» установкой «все доверенного» X509TrustManager в соответствующих местах.
Теперь мне нужно прекратить эту практику (аудит безопасности...).
Я не могу изменить список центров сертификации среды.
Я хотел бы централизованно добавить несколько проблемных листовых и корневых сертификатов. Моей первой мыслью было создать хранилище ключей JKS с сертификатами и зарегистрировать его со следующей опцией JVM:
Код: Выделить всё
-Djavax.net.ssl.trustStore=additional_CAs_truststore.jks
Затем я увидел пример «делегирующего диспетчера доверия», который выглядит так:
Код: Выделить всё
public class TrustManagerDelegate implements X509TrustManager {
private final X509TrustManager mainTrustManager;
private final X509TrustManager fallbackTrustManager;
public TrustManagerDelegate(X509TrustManager mainTrustManager, X509TrustManager fallbackTrustManager) {
this.mainTrustManager = mainTrustManager;
this.fallbackTrustManager = fallbackTrustManager;
}
...
@Override
public void checkServerTrusted(final X509Certificate[] x509Certificates, final String authType) throws CertificateException {
try {
mainTrustManager.checkServerTrusted(x509Certificates, authType);
} catch(CertificateException ignored) {
this.fallbackTrustManager.checkServerTrusted(x509Certificates, authType);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return this.fallbackTrustManager.getAcceptedIssuers();
}
}
Код: Выделить всё
public void run(String... args) throws Exception {
final TrustManagerFactory javaDefaultTrustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
javaDefaultTrustManager.init((KeyStore) null);
final TrustManagerFactory additionalCaTrustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("additional_CAs_truststore.jks");
ks.load(is, "changeit".toCharArray());
is.close();
additionalCaTrustManager.init(ks);
for(X509Certificate x509Certificate : ((X509TrustManager)javaDefaultTrustManager.getTrustManagers()[0]).getAcceptedIssuers()) {
System.out.println("Accepted issuer from java default trust manager: " + x509Certificate.getIssuerX500Principal());
}
for(X509Certificate x509Certificate : ((X509TrustManager)additionalCaTrustManager.getTrustManagers()[0]).getAcceptedIssuers()) {
System.out.println("Accepted issuer from additional trust manages: " + x509Certificate.getIssuerX500Principal());
}
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(
null,
new TrustManager[]{
new TrustManagerDelegate(
(X509TrustManager)additionalCaTrustManager.getTrustManagers()[0],
(X509TrustManager)javaDefaultTrustManager.getTrustManagers()[0]
)
},
secureRandom
);
SSLContext.setDefault(sslContext);
{
String content = Request.get("https://google.com").execute().returnContent().asString();
System.out.println("google.com content length: " + content.length());
}
{
String content = Request.get("https://untrusted-root.badssl.com/").execute().returnContent().asString();
System.out.println("untrusted-root.badssl.com content length: " + content.length());
}
{
String content = Request.get("https://teszt.kv.gov.hu/").execute().returnContent().asString();
System.out.println("teszt.kv.gov.hu content length: " + content.length());
}
}
Но я хотел бы знать, есть ли лучший/более простой способ настроить дополнительные доверенные сертификаты CA поверх общесистемного набора сертификатов CA.
Вот рабочая демонстрация:
/>https://github.com/riskop/merging_trust_manager_demo
Подробнее здесь: https://stackoverflow.com/questions/798 ... -i-cant-ch
Мобильная версия