Comment initialiser un TrustManagerFactory avec de multiples sources de la confiance?
Ma demande a un fichier de clés contenant de confiance des certificats auto-signés pour une utilisation dans le réseau local - dire mykeystore.jks
. Je veux être en mesure de se connecter à des sites publics(dire google.com) ainsi que ceux de mon réseau local à l'aide des certificats auto-signés qui ont été configurés localement.
Le problème ici est que, lorsque je me connecte à https://google.com, chemin de la construction échoue, parce que la définition de mon propre fichier de clés remplace la valeur par défaut du fichier de clés contenant des autorités de certification racine fourni avec le JRE, rapports à l'exception
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Cependant, si je importer un certificat CA dans mon propre fichier de clés (mykeystore.jks
), il fonctionne très bien. Est-il un moyen de soutenir à la fois?
J'ai ma propre TrustManger à cette fin,
public class CustomX509TrustManager implements X509TrustManager {
X509TrustManager defaultTrustManager;
public MyX509TrustManager(KeyStore keystore) {
TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustMgrFactory.init(keystore);
TrustManager trustManagers[] = trustMgrFactory.getTrustManagers();
for (int i = 0; i < trustManagers.length; i++) {
if (trustManagers[i] instanceof X509TrustManager) {
defaultTrustManager = (X509TrustManager) trustManagers[i];
return;
}
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException ce) {
/* Handle untrusted certificates */
}
}
}
J'ai ensuite initialiser le SSLContext,
TrustManager[] trustManagers =
new TrustManager[] { new CustomX509TrustManager(keystore) };
SSLContext customSSLContext =
SSLContext.getInstance("TLS");
customSSLContext.init(null, trustManagers, null);
et de définir la prise en usine,
HttpsURLConnection.setDefaultSSLSocketFactory(customSSLContext.getSocketFactory());
Le programme principal,
URL targetServer = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) targetServer.openConnection();
Si je n'ai pas mis mon propre gestionnaires des fonds, il se connecte à https://google.com l'amende juste. Comment puis-je obtenir un "défaut de confiance manager", qui désigne à la clé par défaut magasin?
OriginalL'auteur varrunr | 2014-04-17
Vous devez vous connecter pour publier un commentaire.
Dans
trustMgrFactory.init(keystore);
de la configuration des defaultTrustManager avec votre propre fichier de clés, pas le système de stockage par défaut.Basée sur la lecture du code source pour le soleil.de sécurité.le protocole ssl.TrustManagerFactoryImpl, il ressemble à
trustMgrFactory.init((KeyStore) null);
serait faire exactement ce dont vous avez besoin (de la charge du système de stockage par défaut), et basé sur des tests rapides, il semble fonctionner pour moi.Mais ce n'est pas de vous laisser utiliser votre certificat personnalisé dans un fichier de clés, seule l'AC les certificats installés sur le système.
Bravo pour comprendre cela en lisant la source! Cela simplifie beaucoup de cacerts chemin d'accès et la gestion des noms de jongleries! Aussi m'étonne qu'il n'y a pas de demande de mot de passe pour elle aussi.
fonctionne pour moi
openjdk version "1.8.0_151"
OriginalL'auteur Pasi
La réponse ici est de savoir comment j'en suis venu à comprendre comment faire. Si vous voulez juste accepter le système CA certs ainsi qu'une housse de magasin de clés de certs je l'ai simplifié en une seule classe avec des méthodes bien pratiques. Le code complet est disponible ici:
https://gist.github.com/HughJeffner/6eac419b18c6001aeadb
OriginalL'auteur Hugh Jeffner
J'ai couru dans le même problème avec les Communes HttpClient. Solution de travail pour mon cas était de créer délégation de la chaîne pour PKIX TrustManagers manière suivante:
Et initialiser HttpClient manière suivante (oui c'est moche):
Dans votre cas simple HttpsURLConnection vous pouvez vous en tirer avec une version simplifiée de délégation de classe:
OriginalL'auteur Novoj
Pour les développeurs Android, cela peut être beaucoup plus facile. En résumé, vous pouvez ajouter un xml res fichier de config personnalisé de votre certs.
Étape 1: ouvrez votre manifeste xml ajouter un attribut.
Étape 2: Ajouter network_security_config.xml pour res/xml, config certs que vous le souhaitez.
Remarque: ce document xml peut supporter de nombreux autres usages, et cette solution ne fonctionne que sur api24+.
Référence officielle: ici
OriginalL'auteur KFJK
Lorsque vous initialisez une SSLContext vous offre un tableau de TrustManagers. Vous offre deux: un par défaut qui utilise le JRE truststore, et un autre qui utilise le vôtre. Le modèle de la délégation s la mauvaise réponse ici.
Seule la première instance d'une clé spécifique et/ou de fiducie, le gestionnaire de mise en œuvre type dans le tableau est utilisé. (Par exemple, seul le premier javax.net.le protocole ssl.X509KeyManager du tableau doit être utilisé.)
OriginalL'auteur user207421