web-dev-qa-db-fra.com

Problèmes avec https (No peer certificate) dans Android

Problème

Je souhaite envoyer une requête https au site https://10.2.20.20/fido/EzPay/login.php mon propre serveur, obtenir une réponse de celui-ci et l'enregistrer, par exemple, dans une chaîne. J'ai trouvé quelques exemples de codes sur Internet et j'essaie de les tester pour mon problème mais ils ne sont pas utiles Ci-dessous, je présente quelques parties de codes que j'ai testées.


Exemple de code:

J'essaie ce code, mais j'obtiens toujours la même exception "Aucun certificat homologue" Pourquoi?

try
{
    HostnameVerifier hostnameVerifier = org.Apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

    DefaultHttpClient client = new DefaultHttpClient();

    SchemeRegistry registry = new SchemeRegistry();
    SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
    socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
    registry.register(new Scheme("https", socketFactory, 443));
    SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
    DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

    // Set verifier      
    HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

    // Example send http request
    final String url = "https://10.2.20.20/fido/EzPay/login.php";
    HttpPost httpPost = new HttpPost(url);
    HttpResponse response = httpClient.execute(httpPost);

    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String line = "";
    while ((line = rd.readLine()) != null) {
        Log.i(DownloadImageTask.class.getName(), line);
    }

}
catch(IOException ex)
{
    Log.e(DownloadImageTask.class.getName(), ex.getMessage());
}

Exception.

03-02 16: 58: 25.234: W/System.err (1868): javax.net.ssl.SSLPeerUnverifiedException: Pas de certificat d'homologue 03-02 16: 58: 25.238: W/System.err (1868): at org.Apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates (SSLSessionImpl.Java:137) 03-02 16: 58: 25.238: W/System.err (1868): à org.Apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.Java:93) 03-02 16: 58: 25.238: W/System.err (1868): à org.Apache.http.conn.ssl.SSLSocketFactory.createSocket (SSLSocketFactory.Java:381) 03-02 16: 58: 25.238: W/System.err (1868): à org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection (DefaultClientConnectionOperator.Java:165) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.Java:164) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.Java:119) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.Java:360) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.Java:555) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.Java:487) 03-02 16: 58: 25.250: W/System.err (1868): à org.Apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.Java:465) 03-02 16: 58: 25.250: W/System.err (1868): à com.https.test.DownloadImageTask.doInBackground (Https_testActivity.Java:78) 03-02 16: 58: 25.250: W/System.err (1868): à com.https.test.DownloadImageTask.doInBackground (Https_testActivity.Java:1) 03-02 16: 58: 25.250: W/System.err (1868): à Android.os.AsyncTask $ 2.call (AsyncTask.Java:264) 03-02 16: 58: 25.253: W/System.err (1868): at Java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.Java:305) 03-02 16: 58: 25.253: W/System.err (1868): à Java.util.concurrent.FutureTask.run (FutureTask.Java:137) 03-02 16: 58: 25.253: W/System.err (1868): at Android.os.AsyncTask $ SerialExecutor $ 1.run (AsyncTask.Java:208) 03-02 16: 58: 25.257: W/System.err (1868): at Java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.Java:1076) 03-02 16: 58: 25.257: W/System.err (1868): à Java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.Java:569) 03-02 16: 58: 25.257: W/System.err (1868): à Java.lang.Thread.run (Thread.Java:856)


Question

Ce que je fais mal et comment je peux résoudre ce problème. Pourquoi ai-je une exception "sans certificat homologue} _"?

Merci.

Édité


Paramètres Windows Server.

<VirtualHost *:443>
  ServerName 10.2.20.20

 Alias /fido/EzPay/ "d:/fido/EzPay/" 
Alias /fido/EzPay "d:/fido/EzPay/" 

<Directory "d:/fido/EzPay/">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
        Order allow,deny
    Allow from all
</Directory>


  # These are the actual SSL directives needed to get it all working!
  SSLEngine on
  SSLCertificateFile C:/wamp/bin/Apache/apache2.2.17/conf/ssl/fidoserver.crt
  SSLCertificateKeyFile C:/wamp/bin/Apache/apache2.2.17/conf/ssl/fidoserver.pem
</VirtualHost>
19
Viktor Apoyan

Enfin, j'ai résolu le problème https. Comme je me suis battu, le problème principal concernait le serveur, plus précisément le certificat . Android ne prend en charge que le certificat «BKS», raison pour laquelle nous ne pouvons pas obtenir de réponse du serveur Afin de résoudre ce problème, j'ai lu plus de 30 articles et finalement trouvé une solution. 

Les étapes que j'ai faites pour résoudre ce problème, vous pouvez voir ci-dessous:

La première chose à faire était de générer un fichier de clés .bks à partir de notre certificat fidoserver.crt. Pour ce faire, j'ai lu cet article et procédez comme suit: 

  1. Ouvrir cmd 
  2. Allez dans le dossier JDK "cd X:\Programmes\Java\Jdk6\bin". 
  3. Appelez la commande suivante:

keytool -import -alias Tomcat -fichier X: //KeyStore/fidoserver.crt -keypass password - magasin de clés X: //KeyStore/keystore.bks -storetype BKS -storepass 222222 -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath X: //KeyStore/bcprov-jdk16-146.jar

Avant d'exécuter cette commande, j'ai téléchargé Bouncy Castle .jar et je le mets dans le dossier des certificats. Après avoir effectué toutes ces étapes, je récupère le fichier keystore.bks, qui est le bon fichier de certificat pour l'application Android. Je mets ce fichier dans le dossier Androids mnc/sdcard. Dans le code Java, j'ai écrit le code suivant pour lire ce fichier keystore.bbk

KeyStore trustStore  = KeyStore.getInstance( "BKS" /*KeyStore.getDefaultType()*/ );
FileInputStream instream = new FileInputStream(new File("/mnt/sdcard/keystore.bks"));
try {
    trustStore.load(instream, "222222".toCharArray());
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (CertificateException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try { instream.close(); } catch (Exception ignore) {}
}

// Create socket factory with given keystore.
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);

SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
Scheme sch = new Scheme("https", socketFactory, 443);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);

HttpGet httpget = new HttpGet("https://10.2.20.20/fido/EzPay/login.php");

System.out.println("executing request " + httpget.getRequestLine());

HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();

System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
    System.out.println("Response content length:  " + entity.getContentLength());
}

// Print html.
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = in.readLine()) != null) {
     System.out.println(line);
}
in.close();

Ceci permet à m de charger notre certificat avec le mot de passe 222222 (mot de passe que nous donnons lorsque nous créons un magasin de clés avec keytool).

Après cela, toutes mes applications de test commencent à fonctionner correctement. Maintenant, je peux envoyer une demande à https et obtenir une réponse. J'ai testé l'application Avec le serveur FIDO, tout fonctionne très bien! Je pense que lundi je ferai quelques changements dans l’application EzPay qui commencera à fonctionner avec des connexions https. 

Références

20
Viktor Apoyan

La méthode de requête POST est inappropriée pour l'URL /. C'est tout ce que nous savons.

L'exemple 1 ne fonctionne pas, car il semble que vous n'êtes pas autorisé à envoyer une demande POST à cette page. Essayer:

/* ... */
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
/* ... */

L'exemple 2 ne fonctionne pas car vous n'acceptez pas le certificat de site Web en tant que certificat accepté. Il devrait donc également être ainsi:

/* ... */
HostnameVerifier hostnameVerifier = org.Apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
/* ... */
7
Caner

Avez-vous essayé d'ouvrir la page avec un navigateur? Si ce n'est pas ouvrir votre configuration est fausse.

Notez que si vous utilisez un certificat auto-signé, vous pouvez rencontrer des problèmes de connexion. Certaines versions du noyau Android (antérieures à la version 2.6.32.9) n’aiment pas les certificats auto-chantés.

0
outofBounds