Je suis tombé sur un fournisseur de certificats qui ne fait pas partie des hôtes de confiance par défaut de la JVM à partir de la date d'entrée en vigueur de l'accord. JDK 8u74
. Le fournisseur est www.identrust.com mais ce n'était pas le domaine auquel j'essayais de me connecter. Ce domaine avait obtenu son certificat auprès de ce fournisseur. Voir La couverture de la racine croisée sera-t-elle assurée par la liste par défaut du JDK/JRE ? -- lire en bas quelques entrées. Voir aussi Quels sont les navigateurs et les systèmes d'exploitation compatibles avec Let's Encrypt ? .
Ainsi, afin de me connecter au domaine qui m'intéressait, qui avait un certificat émis par identrust.com
J'ai suivi les étapes suivantes. En gros, j'ai dû récupérer l'adresse identrust.com ( DST Root CA X3
) pour que la JVM lui fasse confiance. J'ai pu le faire en utilisant Apache HttpComponents 4.5 comme suit :
1 : Obtenez le certificat auprès d'indettrust à l'adresse suivante Instructions de téléchargement de la chaîne de certificats . Cliquez sur le DST Root CA X3 lien.
2 : Sauvegardez la chaîne dans un fichier nommé "DST Root CA X3.pem". Assurez-vous d'ajouter les lignes "-----BEGIN CERTIFICATE-----" et "-----END CERTIFICATE-----" dans le fichier au début et à la fin.
3 : Créez un fichier keystore java, cacerts.jks avec la commande suivante :
keytool -import -v -trustcacerts -alias IdenTrust -keypass yourpassword -file dst_root_ca_x3.pem -keystore cacerts.jks -storepass yourpassword
4 : Copiez le keystore cacerts.jks résultant dans le répertoire des ressources de votre application java/(maven).
5 : Utilisez le code suivant pour charger ce fichier et le joindre au HttpClient d'Apache 4.5. Ceci résoudra le problème pour tous les domaines qui ont des certificats émis par indetrust.com
util oracle inclut le certificat dans le keystore par défaut du JRE.
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File(CalRestClient.class.getResource("/cacerts.jks").getFile()), "yourpasword".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
Lorsque le projet est construit, le fichier cacerts.jks est copié dans le classpath et chargé à partir de là. Je n'ai pas, à ce stade, testé contre d'autres sites ssl, mais si le code ci-dessus "enchaîne" dans ce certificat alors ils fonctionneront aussi, mais encore une fois, je ne sais pas.
Référence : Contexte SSL personnalisé et Comment accepter un certificat auto-signé avec une HttpsURLConnection Java ?
2 votes
Voir Comment accepter un certificat auto-signé avec une HttpsURLConnection Java ? . Évidemment, il serait préférable que vous puissiez faire en sorte que le site utilise un certificat valide.
2 votes
Merci pour le lien, je ne l'avais pas vu en cherchant. Mais les deux solutions proposées impliquent un code spécial pour envoyer une requête et j'utilise un code existant (amazon ws client for java). Respectivement, c'est leur site que je connecte et je ne peux pas résoudre ses problèmes de certificat.
5 votes
@MatthewFlaschen - "Évidemment, ce serait mieux si vous pouviez faire en sorte que le site utilise un cert valide..." - Un certificat auto-signé est un certificat valide si le client lui fait confiance. Beaucoup pensent que le fait de confier la confiance au cartel CA/Navigateur est un défaut de sécurité.
4 votes
En rapport, voir Le code le plus dangereux du monde : la validation des certificats SSL dans les logiciels non-browsers . (Le lien est fourni puisque vous semblez recevoir ces réponses spammy qui désactivent la validation).