Saya mencoba menjalankan kode berikut di android
URLConnection l_connection = null;
// Create connection
uzip=new UnZipData(mContext);
l_url = new URL(serverurl);
if ("https".equals(l_url.getProtocol())) {
System.out.println("<<<<<<<<<<<<< Before TLS >>>>>>>>>>>>");
sslcontext = SSLContext.getInstance("TLS");
System.out.println("<<<<<<<<<<<<< After TLS >>>>>>>>>>>>");
sslcontext.init(null,
new TrustManager[] { new CustomTrustManager()},
new java.security.SecureRandom());
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomHostnameVerifier());
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext
.getSocketFactory());
l_connection = (HttpsURLConnection) l_url.openConnection();
((HttpsURLConnection) l_connection).setRequestMethod("POST");
} else {
l_connection = (HttpURLConnection) l_url.openConnection();
((HttpURLConnection) l_connection).setRequestMethod("POST");
}
/*System.setProperty("http.agent", "Android_Phone");*/
l_connection.setConnectTimeout(10000);
l_connection.setRequestProperty("Content-Language", "en-US");
l_connection.setUseCaches(false);
l_connection.setDoInput(true);
l_connection.setDoOutput(true);
System.out.println("<<<<<<<<<<<<< Before Connection >>>>>>>>>>>>");
l_connection.connect();
Aktif l_connection.connect()
, ini memberikan SSLhandshakeException ini. Kadang-kadang berhasil, tetapi sebagian besar waktu memberikan pengecualian. Ini hanya terjadi pada emulator Android 4.0. Saya mengujinya di Android 4.4 dan 5.0, itu berfungsi dengan baik. Apa penyebabnya? Tolong bantu
STACKTRACE
04-28 15:51:13.143: W/System.err(2915): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.143: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.util.InitiateRMS$2.run(InitiateRMS.java:221)
04-28 15:51:13.153: W/System.err(2915): at java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153: W/System.err(2915): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.153: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153: W/System.err(2915): ... 11 more
04-28 16:42:44.139: W/ResourceType(3140): No package identifier when getting value for resource number 0x00000000
android
ssl
sslhandshakeexception
android-4.0.3-ice-cream-sandwich
Bhavit S. Sengar
sumber
sumber
Jawaban:
Saya menemukan solusinya dengan menganalisis paket data menggunakan wireshark. Apa yang saya temukan adalah bahwa saat membuat sambungan aman, android kembali ke SSLv3 dari TLSv1 . Ini adalah bug di versi android <4.4, dan dapat diatasi dengan menghapus protokol SSLv3 dari daftar Protokol yang Diaktifkan. Saya membuat kelas socketFactory khusus yang disebut NoSSLv3SocketFactory.java. Gunakan ini untuk membuat pabrik soket.
Gunakan kelas ini seperti ini saat menghubungkan:
PERBARUI:
Sekarang, solusi yang benar adalah menginstal penyedia keamanan yang lebih baru menggunakan Layanan Google Play :
Ini secara efektif memberi aplikasi Anda akses ke versi OpenSSL dan Java Security Provider yang lebih baru, yang menyertakan dukungan untuk TLSv1.2 di SSLEngine. Setelah penyedia baru diinstal, Anda dapat membuat SSLEngine yang mendukung SSLv3, TLSv1, TLSv1.1, dan TLSv1.2 dengan cara biasa:
Atau Anda dapat membatasi protokol yang diaktifkan menggunakan
engine.setEnabledProtocols
.Jangan lupa menambahkan dependensi berikut ( periksa versi terbaru di sini ):
Untuk info lebih lanjut, lihat tautan ini .
sumber
Skenario
Saya mendapatkan pengecualian SSLHandshake pada perangkat yang menjalankan versi Android sebelum Android 5.0. Dalam kasus penggunaan saya, saya juga ingin membuat TrustManager untuk mempercayai sertifikat klien saya.
Saya menerapkan NoSSLv3SocketFactory dan NoSSLv3Factory untuk menghapus SSLv3 dari daftar protokol yang didukung klien saya, tetapi saya tidak bisa mendapatkan solusi ini untuk bekerja.
Beberapa hal yang saya pelajari:
Apa yang berhasil untuk saya
Izinkan keamanan Android
Provider
diperbarui saat memulai aplikasi Anda.Penyedia default sebelum 5.0+ tidak menonaktifkan SSLv3. Asalkan Anda memiliki akses ke layanan Google Play, relatif mudah untuk menambal Penyedia keamanan Android dari aplikasi Anda.
Jika Anda sekarang membuat OkHttpClient atau HttpURLConnection TLSv1.1 dan TLSv1.2 harus tersedia sebagai protokol dan SSLv3 harus dihapus. Jika klien / koneksi (atau lebih khusus itu SSLContext) itu dijalankan sebelum memanggil
ProviderInstaller.installIfNeeded(...)
maka perlu diciptakan.Jangan lupa untuk menambahkan dependensi berikut ( versi terbaru ditemukan di sini ):
Sumber:
Ke samping
Saya tidak perlu secara eksplisit mengatur algoritma cipher mana yang harus digunakan klien saya, tetapi saya menemukan posting SO yang merekomendasikan yang dianggap paling aman pada saat penulisan: Cipher Suites mana yang harus diaktifkan untuk SSL Socket?
sumber
Anda juga harus tahu bahwa Anda dapat memaksa TLS v1.2 untuk perangkat Android 4.0 yang tidak mengaktifkannya secara default:
Letakkan kode ini di onCreate () dari file Aplikasi Anda :
sumber
Sebelumnya, saya juga telah memecahkan masalah ini dengan
SSLFactory
implementasi khusus , tetapi menurut dokumen OkHttp solusinya jauh lebih mudah.Solusi terakhir saya dengan
TLS
cipher yang dibutuhkan untuk 4.2+ perangkat terlihat seperti ini:Perhatikan bahwa kumpulan protokol yang didukung bergantung pada konfigurasi di server Anda.
sumber
Saya menemukan solusinya di sini di tautan ini .
Anda hanya perlu menempatkan kode di bawah ini di kelas aplikasi Android Anda. Dan itu sudah cukup. Tidak perlu melakukan perubahan apa pun dalam pengaturan Retrofit Anda. Ini menyelamatkan hari saya.
Semoga ini bisa membantu. Terima kasih.
sumber
Ini menyelesaikannya untuk saya:
android 4.1. aktifkan tls1.1 dan tls 1.2
sumber
Saya juga mendapat masalah laporan kesalahan ini. Kode saya ada di bawah.
Saya memiliki Springboot sebagai backend dan menggunakan Android OKHttp untuk mendapatkan informasi. Kesalahan kritis yang saya buat adalah saya menggunakan .url ( "https : //10.0.2.2: 8010 / getShopInfo / aaa") dalam kode Android. Tapi backend saya tidak diperbolehkan meminta https. Setelah saya menggunakan .url (" http : //10.0.2.2: 8010 / getShopInfo / aaa") , maka kode saya berjalan dengan baik. Jadi, saya ingin mengatakan kesalahan saya bukanlah versi emulator, ini tentang protokol permintaan. Saya menemui masalah lain setelah melakukan apa yang saya katakan, tetapi itu masalah lain, dan saya melampirkan metode penyelesaian masalah baru .
Semoga berhasil!
sumber
Itu dapat direproduksi hanya ketika saya menggunakan proxy pada genymotion (<4.4).
Periksa pengaturan proxy Anda di Pengaturan-> Nirkabel & Jaringan-> WiFi -> (Tekan Lama WiredSSID) -> Ubah Jaringan
Pilih tampilkan opsi lanjutan: setel setelan Proksi ke TIDAK ADA.
sumber
Ketika saya mendapat kesalahan ini, itu karena protokol (versi TLS) dan / atau cipher suite yang didukung oleh server tidak diaktifkan (dan mungkin bahkan tidak didukung oleh) perangkat. Untuk API 16-19, TLSv1.1 dan TLSv1.2 didukung tetapi tidak diaktifkan secara default. Setelah saya mengaktifkannya untuk versi ini, saya masih mendapatkan kesalahan karena versi ini tidak mendukung cipher apa pun di instans AWS CloudFront kami.
Karena tidak mungkin menambahkan cipher ke Android, kami harus mengganti versi CloudFront kami dari TLSv1.2_2018 ke TLSv1.1_2016 (yang masih mendukung TLSv1.2; itu tidak memerlukannya), yang memiliki empat cipher yang didukung oleh versi Android sebelumnya, dua di antaranya masih dianggap kuat.
Pada saat itu, kesalahan menghilang dan panggilan tetap berjalan (dengan TLSv1.2) karena setidaknya ada satu protokol dan setidaknya satu sandi yang dibagikan perangkat dan server.
Lihat tabel di halaman ini untuk mengetahui protokol dan cipher yang didukung dan diaktifkan pada versi Android mana.
Sekarang apakah Android benar-benar mencoba menggunakan SSLv3 seperti yang tersirat oleh bagian "kegagalan jabat tangan peringatan sslv3" dari pesan kesalahan? Aku meragukan itu; Saya menduga ini adalah jaring laba-laba lama di pustaka SSL yang belum dibersihkan tetapi saya tidak bisa memastikannya.
Untuk mengaktifkan TLSv1.2 (dan TLSv1.1), saya dapat menggunakan yang jauh lebih sederhana
SSLSocketFactory
daripada yang terlihat di tempat lain (sepertiNoSSLv3SocketFactory
). Ini hanya memastikan bahwa protokol yang diaktifkan menyertakan semua protokol yang didukung dan bahwa cipher yang diaktifkan menyertakan semua cipher yang didukung (yang terakhir tidak diperlukan untuk saya tetapi bisa untuk orang lain) - lihatconfigure()
di bagian bawah. Jika Anda lebih suka mengaktifkan hanya protokol terbaru, Anda dapat menggantisocket.supportedProtocols
dengan sesuatu sepertiarrayOf("TLSv1.1", "TLSv1.2")
(juga untuk cipher):sumber
Saya memecahkan masalah dengan ini: NoSSLv3SocketFactory.java
Kelas utama:
sumber
Jawaban Saya mendekati jawaban di atas tetapi Anda perlu menulis kelas dengan tepat tanpa mengubah apa pun.
}
dan menggunakannya dengan HttpsURLConnection
sumber