J'utilise Java 6 et j'essaie de créer un HttpsURLConnection
contre un serveur distant, en utilisant un certificat client.
Le serveur utilise un certificat racine auto-signé et requiert la présentation d'un certificat client protégé par mot de passe. J'ai ajouté le certificat racine du serveur et le certificat client à un keystore java par défaut que j'ai trouvé dans /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts
(OSX 10.5). Le nom du fichier keystore semble suggérer que le certificat client n'est pas censé y entrer?
Quoi qu'il en soit, l'ajout du certificat racine à ce magasin a résolu le tristement célèbre javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.
Cependant, je suis maintenant bloqué sur la façon d'utiliser le certificat client. J'ai essayé deux approches et aucune ne m'amène nulle part.
Tout d'abord, et de préférence, essayez:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
J'ai essayé de sauter la classe HttpsURLConnection (pas idéal car je veux parler HTTP avec le serveur), et faites ceci à la place:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out
Je ne suis même pas sûr que le certificat client soit le problème ici.
Réponses:
Enfin résolu;). Vous avez un indice fort ici (la réponse de Gandalfs en a également touché un peu). Les liens manquants étaient (principalement) le premier des paramètres ci-dessous, et dans une certaine mesure, j'ai négligé la différence entre les keystores et les truststores.
Le certificat de serveur auto-signé doit être importé dans un truststore:
Ces propriétés doivent être définies (soit sur la ligne de commande, soit dans le code):
Exemple de code de travail:
la source
Bien que cela ne soit pas recommandé, vous pouvez également désactiver complètement la validation des certificats SSL:
la source
Avez-vous défini les propriétés du système KeyStore et / ou TrustStore?
ou avec le code
Idem avec javax.net.ssl.trustStore
la source
Si vous traitez avec un appel de service Web utilisant le framework Axis, il existe une réponse beaucoup plus simple. Si tout ce que vous voulez, c'est que votre client puisse appeler le service Web SSL et ignorer les erreurs de certificat SSL, inscrivez simplement cette déclaration avant d'appeler des services Web:
System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");
Les clauses de non-responsabilité habituelles selon lesquelles il s'agit d'une très mauvaise chose à faire dans un environnement de production s'appliquent.
J'ai trouvé ceci sur le wiki d'Axis .
la source
Pour moi, c'est ce qui a fonctionné avec Apache HttpComponents ~ HttpClient 4.x:
Le fichier P12 contient le certificat client et la clé privée client, créés avec BouncyCastle:
la source
keyStore
ce qui contient la clé privée et le certificat.J'utilise le package Apache commons HTTP Client pour faire cela dans mon projet actuel et cela fonctionne bien avec SSL et un certificat auto-signé (après l'avoir installé dans des cacerts comme vous l'avez mentionné). Jetez-y un œil ici:
http://hc.apache.org/httpclient-3.x/tutorial.html
http://hc.apache.org/httpclient-3.x/sslguide.html
la source
SSLContext
directement, vous pouvez donc configurer tout cela de cette façon, au lieu d'utiliserAuthSSLProtocolSocketFactory
.Je pense que vous avez un problème avec votre certificat de serveur, ce n'est pas un certificat valide (je pense que c'est ce que signifie «handshake_failure» dans ce cas):
Importez votre certificat de serveur dans votre keystore trustcacerts sur le JRE du client. Cela se fait facilement avec keytool :
la source
Utilisation du code ci-dessous
ou
n'est pas du tout nécessaire. Il n'est pas non plus nécessaire de créer votre propre usine SSL personnalisée.
J'ai également rencontré le même problème, dans mon cas, il y avait un problème qui complète la chaîne de certificats n'était pas importée dans les magasins de confiance. Importez des certificats à l'aide de l'utilitaire keytool à droite du certificat racine, vous pouvez également ouvrir le fichier cacerts dans le bloc-notes et voir si la chaîne de certificats complète est importée ou non. Vérifiez le nom d'alias que vous avez fourni lors de l'importation de certificats, ouvrez les certificats et voyez combien il en contient, le même nombre de certificats devrait être présent dans le fichier cacerts.
Le fichier cacerts doit également être configuré sur le serveur sur lequel vous exécutez votre application, les deux serveurs s'authentifieront mutuellement avec des clés publiques / privées.
la source