web-dev-qa-db-fra.com

HTTPS GET (SSL) avec Android et certificat de serveur auto-signé

J'ai examiné divers articles sur la façon de récupérer quelque chose via HTTPS sur Android, à partir d'un serveur utilisant un certificat auto-signé. Cependant, aucun d'entre eux ne semble fonctionner - ils ne parviennent pas tous à supprimer le 

javax.net.ssl.SSLException: Message de certificat de serveur non approuvé. 

Ce n'est pas une option de modifier le serveur pour avoir un certificat approuvé, ni de faire en sorte que le certificat de serveur corresponde à l'adresse IP du serveur.

Notez que le serveur n'aura pas de nom DNS, il n'aura qu'une adresse IP. La requête GET ressemble à ceci:

 https://username:password@anyIPAddress/blabla/index.php?param=1&param2=3

Je suis pleinement conscient du fait que cette solution est sujette aux attaques de type homme du milieu, etc.

La solution doit donc ignorer le manque de confiance dans le certificat et ignorer la non correspondance des noms d'hôte.

Est-ce que quelqu'un connaît le code, ça le fait, en utilisant Java pour Android?

Il y a beaucoup de tentatives pour expliquer cela sur stackoverflow.com , et beaucoup d'extraits de code, mais ils ne semblent pas fonctionner, et personne n'a fourni un bloc de code qui résout ce problème, autant que je sache. . Il serait intéressant de savoir si quelqu'un a vraiment résolu ce problème ou si Android bloque simplement les certificats qui ne sont pas fiables.

32
Lars D

J'ai créé une application qui utilise l'auto-signature ou qui fait confiance à tous les certificats. La source est ici: http://code.google.com/p/meneameandroid/source/browse/#svn/trunk/src/com/dcg/auth et libre d'utilisation: P

Il suffit d’utiliser le gestionnaire HttpManager et de créer la fabrique SSL à l’aide de la clé de confiance: http://code.google.com/p/meneameandroid/source/browse/trunk/src/com/dcg/util/HttpManager.Java

EDIT: Liens mis à jour

36
Moss

Comme vous l'avez correctement souligné, il existe deux problèmes: a) le certificat n'est pas fiable et b) le nom du certificat ne correspond pas au nom d'hôte.

AVERTISSEMENT: pour quiconque arrive à cette réponse, c’est un sale bidouillage horrible et vous ne devez pas utilisez-le pour tout ce qui compte. SSL/TLS sans authentification est pire que pas de cryptage du tout - lire et modifier vos données "cryptées" est trivial pour un attaquant et vous ne sauriez même pas que cela se passait .

Encore avec moi? Je craignais tellement ...

a) est résolu en créant un SSLContext personnalisé dont TrustManager accepte tout:

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] {
  new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
  }
}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

et b) en créant un HostnameVerifier qui permet à la connexion de continuer même si le certificat ne correspond pas au nom d'hôte:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    return true;
  }
});

Les deux doivent avoir lieu dès le début de votre code, avant de commencer à jouer avec HttpsURLConnections et ainsi de suite. Cela fonctionne à la fois sous Android et dans l'environnement JRE. Prendre plaisir.

35
SimonJ
6
Maciek Sawicki

Si vous utilisez une connexion HttpsURLConnection, essayez d’appeler setHostnameVerifier dessus avant connect() et de lui transmettre une HostnameVerifier qui accepte sans tenir compte de la véracité.

6
Yuliy

Si vous avez un accès aux périphériques, vous pouvez ajouter le certificat à un magasin de clés. Voir plus d'informations ici .

D'autre part, vous pouvez utiliser this method, mais je pense que c'est un peu moche.


Ressources :

Sur le même sujet:

2
Colin Hebert

Si vous me demandez, faites-le de manière sécurisée. 

J'ai trouvé un bon tutoriel http://blog.antoine.li/index.php/2010/10/Android-trusting-ssl-certificates/ et ce n'est vraiment pas difficile à mettre en œuvre.

Le tutoriel recommandé par Maciek est également très bon.

Je l'ai testé et cela fonctionne sans problème dans mon application.

1
saxos

J'ai créé une application qui utilise un certificat auto-signé il y a 4 mois. Voici le code que j'espère que cela aide: https://bitbucket.org/momo0002/tlsdemo.git

0
moji