À l'aide de HttpClient , le message d'erreur suivant s'affiche lors d'une tentative de communication via HTTPS:
Exception dans le fil "principal" javax.net.ssl.SSLPeerUnverifiedException: homologue non authentifié.
Voici mon code:
URI loginUri = new URI("https://myUrl.asp");
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet( loginUri );
HttpResponse response = httpclient.execute( httpget );
Comment supprimer ou supprimer cette erreur?
En utilisant HttpClient 3.x, vous devez procéder comme suit:
Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", easyHttps);
Une implémentation de EasySSLProtocolSocketFactory peut être trouvée ici .
Remarque: Ne le faites pas dans le code de production, utilisez plutôt http ou la clé publique auto-signée, comme suggéré ci-dessus.
Sur HttpClient 4.xx:
import static org.junit.Assert.assertEquals;
import Java.security.KeyManagementException;
import Java.security.NoSuchAlgorithmException;
import Java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.Apache.http.HttpResponse;
import org.Apache.http.client.methods.HttpGet;
import org.Apache.http.conn.scheme.Scheme;
import org.Apache.http.conn.ssl.SSLSocketFactory;
import org.Apache.http.impl.client.DefaultHttpClient;
import org.junit.Test;
public class HttpClientTrustingAllCertsTest {
@Test
public void shouldAcceptUnsafeCerts() throws Exception {
DefaultHttpClient httpclient = httpClientTrustingAllSSLCerts();
HttpGet httpGet = new HttpGet("https://Host_with_self_signed_cert");
HttpResponse response = httpclient.execute( httpGet );
assertEquals("HTTP/1.1 200 OK", response.getStatusLine().toString());
}
private DefaultHttpClient httpClientTrustingAllSSLCerts() throws NoSuchAlgorithmException, KeyManagementException {
DefaultHttpClient httpclient = new DefaultHttpClient();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, getTrustingManager(), new Java.security.SecureRandom());
SSLSocketFactory socketFactory = new SSLSocketFactory(sc);
Scheme sch = new Scheme("https", 443, socketFactory);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
return httpclient;
}
private TrustManager[] getTrustingManager() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Do nothing
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Do nothing
}
} };
return trustAllCerts;
}
}
Cette réponse fait suite aux réponses de owlstead et Mat . Cela s'applique aux installations SE/EE et non aux SSL ME/mobile/Android.
Comme personne ne l’a encore mentionné, je mentionnerai le «moyen de production» pour résoudre ce problème: Suivez les étapes de la classe AuthSSLProtocolSocketFactory dans HttpClient pour mettre à jour votre magasin de clés de confiance et vos magasins de clés.
keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
(auto-signe ou faire signer votre certificat)
Importer le certificat racine de l'autorité de certification approuvée
keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
keytool -list -v -keystore my.keystore
Si vous ne possédez pas de certificat de serveur, générez-en un au format JKS, puis exportez-le sous forme de fichier CRT. Source: documentation keytool
keytool -genkey -alias server-alias -keyalg RSA -keypass changeit
-storepass changeit -keystore my.keystore
keytool -export -alias server-alias -storepass changeit
-file server.crt -keystore my.keystore
Cette exception survient dans le cas où votre serveur est basé sur JDK 7 et que votre client est sur JDK 6 et utilise des certificats SSL. Le protocole de transfert de message sslv2hello dans JDK 7 est désactivé par défaut, tandis que le protocole de transfert de message sslv2hello dans JDK 6 est activé. Pour cette raison, lorsque votre client tente de se connecter au serveur, un message sslv2hello sera envoyé au serveur et, en raison du message sslv2hello désactivé, vous obtiendrez cette exception. Pour résoudre ce problème, vous devez déplacer votre client vers JDK 7 ou utiliser la version 6u91 de JDK. Mais pour obtenir cette version de JDK, vous devez obtenir le
Méthode renvoyant un "secureClient" (dans un environnement Java 7 - NetBeans IDE et GlassFish Server: port https par défaut 3920), espérons que cela pourrait aider:
public DefaultHttpClient secureClient() {
DefaultHttpClient httpclient = new DefaultHttpClient();
SSLSocketFactory sf;
KeyStore trustStore;
FileInputStream trustStream = null;
File truststoreFile;
// Java.security.cert.PKIXParameters for the trustStore
PKIXParameters pkixParamsTrust;
KeyStore keyStore;
FileInputStream keyStream = null;
File keystoreFile;
// Java.security.cert.PKIXParameters for the keyStore
PKIXParameters pkixParamsKey;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
truststoreFile = new File(TRUSTSTORE_FILE);
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keystoreFile = new File(KEYSTORE_FILE);
try {
trustStream = new FileInputStream(truststoreFile);
keyStream = new FileInputStream(keystoreFile);
} catch (FileNotFoundException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
trustStore.load(trustStream, PASSWORD.toCharArray());
keyStore.load(keyStream, PASSWORD.toCharArray());
} catch (IOException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (CertificateException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
pkixParamsTrust = new PKIXParameters(trustStore);
// accepts Server certificate generated with keytool and (auto) signed by Sun
pkixParamsTrust.setPolicyQualifiersRejected(false);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
pkixParamsKey = new PKIXParameters(keyStore);
// accepts Client certificate generated with keytool and (auto) signed by Sun
pkixParamsKey.setPolicyQualifiersRejected(false);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
sf = new SSLSocketFactory(trustStore);
ClientConnectionManager manager = httpclient.getConnectionManager();
manager.getSchemeRegistry().register(new Scheme("https", 3920, sf));
} catch (KeyManagementException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnrecoverableKeyException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (KeyStoreException ex) {
Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
}
// use the httpclient for any httpRequest
return httpclient;
}