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