Baru-baru ini diposting pertanyaan mengenai HttpClient
overttp ( ditemukan di sini ). Saya telah membuat beberapa kemajuan, tetapi saya mengalami masalah baru. Seperti masalah terakhir saya, sepertinya saya tidak dapat menemukan contoh di mana saja yang cocok untuk saya. Pada dasarnya, saya ingin klien saya menerima sertifikat apa pun (karena saya hanya menunjuk ke satu server) tetapi saya tetap mendapatkanjavax.net.ssl.SSLException: Not trusted server certificate exception.
Jadi inilah yang saya miliki:
public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {
HttpPost post = new HttpPost(new URI(PROD_URL));
post.setEntity(new StringEntity(BODY));
KeyStore trusted = KeyStore.getInstance("BKS");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme ("https", sslf, 443));
SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
schemeRegistry);
HttpClient client = new DefaultHttpClient(cm, post.getParams());
HttpResponse result = client.execute(post);
}
Dan inilah kesalahan yang saya dapatkan:
W/System.err( 901): javax.net.ssl.SSLException: Not trusted server certificate
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360)
W/System.err( 901): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321)
W/System.err( 901): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
W/System.err( 901): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
W/System.err( 901): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
W/System.err( 901): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:129)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.access$0(MainActivity.java:77)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity$2.run(MainActivity.java:49)
W/System.err( 901): Caused by: java.security.cert.CertificateException: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:157)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:355)
W/System.err( 901): ... 12 more
W/System.err( 901): Caused by: java.security.InvalidAlgorithmParameterException: the trust anchors set is empty
W/System.err( 901): at java.security.cert.PKIXParameters.checkTrustAnchors(PKIXParameters.java:645)
W/System.err( 901): at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.<init>(TrustManagerImpl.java:89)
W/System.err( 901): at org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.java:134)
W/System.err( 901): at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.java:226)W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.createTrustManagers(SSLSocketFactory.java:263)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:190)
W/System.err( 901): at org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:216)
W/System.err( 901): at me.harrisonlee.test.ssl.MainActivity.connect(MainActivity.java:107)
W/System.err( 901): ... 2 more
java
ssl
https
certificate
apache-httpclient-4.x
harrisonlee
sumber
sumber
Jawaban:
Catatan: Jangan menerapkan ini dalam kode produksi yang akan Anda gunakan pada jaringan yang tidak sepenuhnya Anda percayai. Terutama apa pun yang terjadi melalui internet publik.
Pertanyaan Anda adalah apa yang ingin saya ketahui. Setelah saya melakukan beberapa pencarian, kesimpulannya adalah sebagai berikut.
Dengan cara HttpClient, Anda harus membuat kelas khusus dari org.apache.http.conn.ssl.SSLSocketFactory, bukan yang org.apache.http.conn.ssl.SSLSocketFactory itu sendiri. Beberapa petunjuk dapat ditemukan di pos ini Penanganan SSL kustom berhenti berfungsi di Android 2.2 FroYo .
Contohnya seperti ...
dan gunakan kelas ini saat membuat instance dari HttpClient.
BTW, tautan di bawah ini untuk seseorang yang mencari solusi HttpURLConnection. Koneksi Https Android
Saya telah menguji dua macam solusi di atas pada froyo, dan semuanya bekerja seperti pesona dalam kasus saya. Akhirnya, menggunakan HttpURLConnection mungkin menghadapi masalah pengalihan, tetapi ini di luar topik.
Catatan: Sebelum Anda memutuskan untuk mempercayai semua sertifikat, Anda mungkin harus mengetahui situs dengan baik dan tidak akan merusaknya bagi pengguna akhir.
Memang, risiko yang Anda ambil harus dipertimbangkan dengan hati-hati, termasuk efek situs tiruan peretas yang disebutkan dalam komentar berikut yang sangat saya hargai. Dalam beberapa situasi, meskipun mungkin sulit untuk mengurus semua sertifikat, Anda sebaiknya mengetahui kelemahan tersirat untuk mempercayai semuanya.
sumber
getAcceptedIssuers()
tidak diizinkan untuk mengembalikan nol.Pada dasarnya Anda memiliki empat solusi potensial untuk memperbaiki pengecualian "Tidak Tepercaya" di Android menggunakan httpclient:
Jawaban ini menggunakan solusi # 4, yang menurut saya paling kuat.
Solusinya adalah dengan menggunakan SSLSocketFactory yang dapat menerima beberapa KeyStores, memungkinkan Anda untuk memasok KeyStore Anda sendiri dengan sertifikat Anda sendiri. Ini memungkinkan Anda memuat sertifikat tingkat atas tambahan seperti Thawte yang mungkin hilang pada beberapa perangkat Android. Ini juga memungkinkan Anda untuk memuat sertifikat yang Anda tandatangani sendiri juga. Ini akan menggunakan sertifikat perangkat bawaan bawaan terlebih dahulu, dan kembali pada sertifikat tambahan Anda hanya jika diperlukan.
Pertama, Anda ingin menentukan sertifikat mana yang Anda lewatkan di KeyStore Anda. Jalankan perintah berikut:
Dan Anda akan melihat output seperti berikut:
Seperti yang Anda lihat, sertifikat root kami dari Thawte. Buka situs web penyedia Anda dan temukan sertifikat yang sesuai. Bagi kami, itu ada di sini , dan Anda dapat melihat bahwa yang kami butuhkan adalah hak cipta 2006.
Jika Anda menggunakan sertifikat yang ditandatangani sendiri, Anda tidak perlu melakukan langkah sebelumnya karena Anda sudah memiliki sertifikat yang ditandatangani.
Kemudian, buat file keystore yang berisi sertifikat penandatanganan yang hilang. Crazybob memiliki detail cara melakukan ini di Android , tetapi idenya adalah melakukan hal berikut:
Jika Anda belum memilikinya, unduh perpustakaan penyedia kastil goyang dari: http://www.bouncycastle.org/latest_releases.html . Ini akan menuju classpath Anda di bawah ini.
Jalankan perintah untuk mengekstrak sertifikat dari server dan membuat file pem. Dalam hal ini, mycert.pem.
Kemudian jalankan perintah berikut untuk membuat keystore.
Anda akan melihat bahwa skrip di atas menempatkan hasilnya
res/raw/mystore.bks
. Sekarang Anda memiliki file yang akan Anda muat ke dalam aplikasi Android Anda yang menyediakan sertifikat yang hilang.Untuk melakukan ini, daftarkan SSLSocketFactory Anda ke skema SSL:
Untuk membuat SSLSocketFactory Anda:
Dan akhirnya, kode AdditionalKeyStoresSSLSocketFactory, yang menerima KeyStore baru Anda dan memeriksa apakah KeyStore bawaan gagal memvalidasi sertifikat SSL:
sumber
http://stackoverflow.com/questions/7822381/need-help-understanding-certificate-chains
Tambahkan kode ini sebelum
HttpsURLConnection
dan itu akan dilakukan. Saya mendapatkannya.Saya harap ini membantu Anda.
sumber
Ini ide yang buruk. Mempercayai sertifikat apa pun hanya (sangat) sedikit lebih baik daripada tidak menggunakan SSL sama sekali. Ketika Anda mengatakan "Saya ingin klien saya menerima sertifikat apa pun (karena saya hanya menunjuk ke satu server)" Anda menganggap ini berarti bahwa entah bagaimana menunjuk ke "satu server" aman, yang bukan pada jaringan publik.
Anda benar-benar terbuka terhadap serangan man-in-the-middle dengan mempercayai sertifikat apa pun. Siapa pun dapat mem-proxy koneksi Anda dengan membuat koneksi SSL terpisah dengan Anda dan dengan server akhir. MITM kemudian memiliki akses ke seluruh permintaan dan respons Anda. Kecuali Anda tidak benar-benar membutuhkan SSL di tempat pertama (pesan Anda tidak memiliki sensitif, dan tidak melakukan otentikasi) Anda tidak boleh mempercayai semua sertifikat secara membabi buta.
Anda harus mempertimbangkan menambahkan sertifikat publik ke jks menggunakan keytool, dan menggunakannya untuk membangun pabrik soket Anda, seperti ini:
Ini memiliki satu peringatan yang harus diperhatikan. Sertifikat akan berakhir pada akhirnya, dan kode akan berhenti berfungsi pada saat itu. Anda dapat dengan mudah menentukan kapan ini akan terjadi dengan melihat sertifikat.
sumber
null
diSSLContext.init). You should also use the default algorithms (KMF/TMF.getDefaultAlgorithm() ), instead of hard-coding
SunX509` (lebih karena default untuk TMF sebenarnyaPKIX
pada Sun / Oracle JVM)myjks.jks
datangnya?Anda dapat menonaktifkan HttpURLConnection SSL memeriksa untuk tujuan pengujian dengan cara ini sejak API 8:
sumber
org.apache.http.conn.ssl.AllowAllHostnameVerifier
sudah ditinggalkan.AllowAllHostnameVerifier
digantikan olehNoopHostnameVerifier
"API HttpComponents telah berubah. Ini berfungsi dengan kode di bawah ini.
sumber
Kode di atas dalam https://stackoverflow.com/a/6378872/1553004 benar, kecuali itu HARUS juga memanggil verifier nama host:
Saya mendaftar ke stackoverflow secara tegas untuk menambahkan perbaikan ini. Perhatikan peringatan saya!
sumber
Saya menambahkan respons untuk mereka yang menggunakan httpclient-4.5, dan mungkin bekerja untuk 4.4 juga.
sumber
Memercayai semua sertifikat bukanlah alternatif nyata bagi saya, jadi saya melakukan yang berikut untuk mendapatkan HttpsURLConnection untuk mempercayai sertifikat baru (lihat juga http://nelenkov.blogspot.jp/2011/12/using-custom-certificate-trust-store- on.html ).
Dapatkan sertifikat; Saya menyelesaikan ini dengan mengekspor sertifikat di Firefox (klik pada ikon kunci kecil, dapatkan detail sertifikat, klik ekspor), lalu gunakan portecle untuk mengekspor truststore (BKS).
Muat Truststore dari /res/raw/geotrust_cert.bks dengan kode berikut:
sumber
IOExceptionjavax.net.ssl.SSLPeerUnverifiedException: No peer certificate
. Ini ketika melakukan panggilan eksekusi aktual pada HttpClient setelah pengaturan di atas dilakukan.Ini adalah versi yang lebih sederhana menggunakan kode httpclient 4.1.2. Ini kemudian dapat dimodifikasi untuk setiap algoritma kepercayaan yang Anda inginkan.
sumber
Saya melihat respons dari "emmby" (dijawab 16 Jun 11 pada 21:29), item # 4: "Buat custom SSLSocketFactory yang menggunakan KeyStore sertifikat bawaan, tetapi kembali menggunakan KeyStore alternatif untuk apa pun yang gagal untuk memverifikasi dengan default. "
Ini adalah implementasi yang disederhanakan. Muat sistem keystore & gabungkan dengan aplikasi keystore.
Mode sederhana untuk mengkonversi dari JKS ke BKS:
* Catatan: Di Android 4.0 (ICS) Trust Store telah berubah, info lebih lanjut: http://nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html
sumber
Bagi mereka yang ingin mengizinkan semua sertifikat bekerja (untuk tujuan pengujian) di atas OAuth, ikuti langkah-langkah ini:
1) Unduh kode sumber API Android OAuth di sini: https://github.com/kaeppler/signpost
2) Temukan file "CommonsHttpOAuthProvider" kelas
3) Ubah seperti di bawah ini:
"MySSLSocketFactory" di atas didasarkan pada jawaban yang diterima. Untuk membuatnya lebih mudah, inilah kelas lengkapnya:
}
Semoga ini bisa membantu seseorang.
sumber
HttpClient
dan HTTPS; bukan OAuth untuk Android dari proyek GitHub.Saya menggunakan ini dan ini bekerja untuk saya di semua OS.
sumber
Hanya menambah
-Dtrust_all_cert=true
argumen VM harus dilakukan. Argumen ini memberitahu java untuk mengabaikan pemeriksaan sertifikat.sumber
Siapa pun yang masih berjuang dengan StartCom SSL Certificates di Android 2.1 kunjungi https://www.startssl.com/certs/ dan unduh ca.pem, sekarang dalam jawaban yang diberikan oleh @emmby ganti
dengan
Harus bekerja di luar kotak. Saya berjuang untuk lebih dari satu hari bahkan setelah jawaban sempurna oleh @emmby .. Semoga ini bisa membantu seseorang ...
sumber
gunakan kelas ini
}
sumber
masukkan deskripsi gambar di sini
Sspi gagal di xamarin android.
Saya menemukan solusi ini; letakkan kode ini sebelum Anda menekan tautan HTTPS
sumber
bekerja dengan semua https
sumber
Ada banyak jawaban di atas tetapi saya tidak dapat membuat mereka bekerja dengan benar (dengan waktu terbatas saya), jadi bagi siapa pun yang berada dalam situasi yang sama Anda dapat mencoba kode di bawah ini yang bekerja dengan sempurna untuk tujuan pengujian java saya:
dan panggil seperti:
Referensi: http://tech.chitgoks.com/2011/04/24/how-to-avoid-javax-net-ssl-sslpeerunifiedexception-peer-not-authenticated-problem-menggunakan-apache-httpclient/
sumber
Cukup gunakan ini -
sumber
Jawaban Daniel baik, kecuali saya harus mengubah kode ini ...
ke kode ini ...
untuk membuatnya bekerja.
sumber