So richten Sie zusätzliche CA-Zertifikate *zusätzlich zu* den Standardeinstellungen in Java ein. Ich kann die systemweitJava

Java-Forum
Anonymous
 So richten Sie zusätzliche CA-Zertifikate *zusätzlich zu* den Standardeinstellungen in Java ein. Ich kann die systemweit

Post by Anonymous »

In einer ziemlich großen Anwendung besteht die Notwendigkeit, eine Verbindung zu verschiedenen https://...-Hosts herzustellen (Webdienste, Restdienste, HTML-Scraping usw.).
Viele der Hosts leiden unter verschiedenen SSL-Problemen (selbstsigniertes Zertifikat, unterbrochene Zertifikatskette) oder das Stammzertifikat befindet sich einfach nicht in der systemweiten Liste der vertrauenswürdigen Zertifizierungsstellen.
Bisher wurde das Problem durch die Einstellung „Alles vertrauend“ „gelöst“. X509TrustManager an den entsprechenden Stellen.
Jetzt muss ich diese Praxis beenden (Sicherheitsüberprüfung...).
Ich kann die CA-Liste der Umgebung nicht ändern.
Ich möchte die wenigen problematischen Leaf-Zertifikate und Root-Zertifikate zentral hinzufügen. Mein erster Gedanke war, einen JKS-Keystore mit den Zertifikaten zu erstellen und ihn mit der folgenden JVM-Option zu registrieren:

Code: Select all

-Djavax.net.ssl.trustStore=additional_CAs_truststore.jks
Das Ergebnis ist jedoch, dass die systemweiten Zertifikate dann nicht berücksichtigt werden und die Anwendung nur eine Verbindung zu den „problematischen“ Websites herstellen kann, und nicht beispielsweise zu „https://google.com“.
Dann habe ich ein Beispiel für einen „delegierenden Vertrauensmanager“ gesehen, der so aussieht:

Code: Select all

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();
}
}
Mit diesem Trust Manager würde mein Code so aussehen:

Code: Select all

    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());
}

}
Das Obige funktioniert, und es gefällt mir sehr gut.
Aber ich würde gerne wissen, ob es eine bessere/einfachere Möglichkeit gibt, zusätzliche vertrauenswürdige CA-Zertifikate zusätzlich zum systemweiten Satz von CA-Zertifikaten einzurichten.
Hier ist eine funktionierende Demo:
https://github.com/riskop/merging_trust_manager_demo

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post