Как настроить дополнительные сертификаты CA *поверх* значений по умолчанию в Java. Я не могу изменить общесистемный списJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как настроить дополнительные сертификаты CA *поверх* значений по умолчанию в Java. Я не могу изменить общесистемный спис

Сообщение Anonymous »

В довольно большом приложении возникает необходимость подключения к различным хостам https://... (веб-сервисы, службы отдыха, очистка HTML и т. д.).
Многие хосты страдают от различных проблем с SSL (самозаверяющий сертификат, нарушенная цепочка сертификатов) или просто корневой сертификат не находится в общесистемном списке доверенных центров сертификации.
До сих пор проблема была «решена» установкой «все доверенного» X509TrustManager в соответствующих местах.
Теперь мне нужно прекратить эту практику (аудит безопасности...).
Я не могу изменить список центров сертификации среды.
Я хотел бы централизованно добавить несколько проблемных листовых и корневых сертификатов. Моей первой мыслью было создать хранилище ключей JKS с сертификатами и зарегистрировать его со следующей опцией JVM:

Код: Выделить всё

-Djavax.net.ssl.trustStore=additional_CAs_truststore.jks
Однако в результате общесистемные сертификаты тогда не учитываются, и приложение может подключаться только к «проблемным» сайтам, а не например к «https://google.com».
Затем я увидел пример «делегирующего диспетчера доверия», который выглядит так:

Код: Выделить всё

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://github.com/riskop/merging_or_de ... nager_demo

Подробнее здесь: https://stackoverflow.com/questions/798 ... -i-cant-ch
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»