web-dev-qa-db-fra.com

HttpGet avec HTTPS: SSLPeerUnverifiedException

À 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?

36
Stefan Kendall

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 .

12
Stefan Kendall

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;
    }
}
17
Jonas Andersson

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.

  1. Importer un certificat de confiance et générer un fichier de clés certifiées

keytool -import -alias "my server cert" -file server.crt -keystore my.truststore

  1. Générer une nouvelle clé (utilisez le même mot de passe que le magasin de clés de confiance)

keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore

  1. Émettre une demande de signature de certificat (CSR)

keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore

  1. (auto-signe ou faire signer votre certificat)

  2. Importer le certificat racine de l'autorité de certification approuvée

keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore

  1. Importer le fichier PKCS # 7 contenant la chaîne de certificats complète

keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore

  1. Vérifier le contenu du fichier de clés résultant

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
16
Barett

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 

4
Tanuj Kumar

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;
}
0
user2045005