HttpClient échoue avec Handshake a échoué dans Android 5.0 Lollipop
DefaultHttpClient dans Android 5.0 Lollipop semble être rompu. Il ne peut pas paramétrer la connexion à certains sites qui ont été fixés par les versions précédentes d'Android.
Par exemple j'essaie de me connecter à https://uralsg.megafon.ru
//Create httpclient like in https://stackoverflow.com/questions/18523784/ssl-tls-protocols-and-cipher-suites-with-the-androidhttpclient
HttpClient client = new DefaultHttpClient(manager, params);
HttpGet httpGet = new HttpGet("https://uralsg.megafon.ru");
HttpResponse client = httpclient.execute(httpGet);
Ce code fonctionne sous Android 2.3-4.4, mais échoue sur Android 5.0 (appareils et l'émulateur) avec l'erreur de Connexion fermée par des pairs.
Bien sûr, cela est compréhensible parce que Android 5.0 essaie de se connecter à ce serveur ancien avec TLSv1.2 et modernes chiffrements et elle ne les supporte pas.
Ok, à l'aide de l'exemple de code dans Les protocoles SSL/TLS et suites de chiffrement avec la AndroidHttpClient nous limitons le protocole et cipher TLSv1 et SSL_RSA_WITH_RC4_128_MD5. Maintenant, il échoue avec une erreur différents:
javax.net.ssl.SSLHandshakeException: Handshake failed
caused by
error:140943FC:SSL routines:SSL3_READ_BYTES:sslv3 alert bad record mac
(external/openssl/ssl/s3_pkt.c:1286 0x7f74c1ef16e0:0x00000003)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake
Et bien sûr, ce code fonctionne bien sur Android 2.3-4.4.
J'ai examiné le trafic avec wireshark:
302 4002.147873000 192.168.156.30 83.149.32.13 TLSv1 138 Client Hello
303 4002.185362000 83.149.32.13 192.168.156.30 TLSv1 133 Server Hello
304 4002.186700000 83.149.32.13 192.168.156.30 TLSv1 1244 Certificate
305 4002.186701000 83.149.32.13 192.168.156.30 TLSv1 63 Server Hello Done
307 4002.188117000 192.168.156.30 83.149.32.13 TLSv1 364 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
308 4002.240695000 83.149.32.13 192.168.156.30 TLSv1 61 Alert (Level: Fatal, Description: Bad Record MAC)
Vous pouvez voir que la connexion a été établie, mais le serveur a alerté parce qu'il ne pouvait sans doute pas décoder crypté message de handshake.
Je n'ai pas réussi à vous connecter à https://uralsg.megafon.ru à l'aide de HttpClient sur Android 5.0. Stock navigateur se connecte bien. Android 2.3-4.4 se connecte à ce site de quelque manière sans aucune difficulté.
Est-il un moyen de le rendre possible pour HttpClient pour connecter de tels sites? Ce n'est qu'un exemple, je suis sûr qu'il ya beaucoup de serveurs legacy qui n'a pas pu être reliés par Android 5.0 et HttpClient.
source d'informationauteur Dmitry Kochin
Vous devez vous connecter pour publier un commentaire.
mise à jour: il s'est avéré être un bug dans le back-end, pas android 5si en effet avec le chiffre en question.
J'ai eu le même problème. Pour moi, il s'est avéré être la clef de chiffrement
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
qui a été choisi à partir d'android 5 (mis à jour) de l'ensemble des algorithmes de chiffrement par défaut.Dès que je l'ai retiré de la liste des clients de l'acceptable, les algorithmes, les connexions a de nouveau fonctionné.
La android 5 le journal des modifications mentionne:
Je suis assez sûr que c'est le coupable. Dès que
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
est préféré (par le serveur), la connexion échouera.Noter que
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
œuvres.Ma conjecture est que soit le Android de mise en œuvre de
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
est buggé, ou celle du serveur qui vous parlez.Solutions:
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
de la disposition des algorithmes sur le serveur (pas d'application de redéploiement nécessaire).TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
à partir de la liste des chiffrements par le client de l'offre (au cours de laCLIENT_HELLO
).Vous pouvez le faire sur le côté client par la mise en œuvre de votre propre SSLSocketFactory et de l'appel de
sur SSLSocket création.
edit: noter que ce n'est pas nécessairement un android bug, il se peut que le serveur de mise en œuvre est défectueux. si votre problème est en effet causé par l'algorithme de chiffrement, veuillez laisser un commentaire sur l'android bug tracker](https://code.google.com/p/android/issues/detail?id=81603). merci!!!!
J'ai essayé de changer les cipherSuites dans un socket personnalisé usine, mais cela n'a pas aidé. Dans mon cas, j'ai dû enlever le TLSv1.1 et TLSv1.2 les protocoles de la prise de EnabledProtocols. Il semble que certains anciens serveurs ne gère pas le protocole de négociation pour les nouveaux protocoles très bien. Il existe de nombreux exemples pour la création d'un socket personnalisé de l'usine, tels que Comment remplacer la cipherlist envoyé au serveur par Android lors de l'utilisation de HttpsURLConnection?et les autres pour Apache sockets. Cela étant fait, je viens d'appeler le suivant AdjustSocket méthode pour supprimer les protocoles.