Kata pengantar
Baru -baru ini, masalah yang terkait dengan HTTPS perlu diselesaikan, jadi saya menghabiskan waktu mempelajari penggunaan platform Android HTTPS, dan pada saat yang sama, saya juga membaca beberapa prinsip HTTPS.
Prinsip https
HTTPS (Hyper Text Transfer Protocol Secure) adalah HTTP berdasarkan SSL/TLS. Protokol HTTPS didasarkan pada protokol HTTP, menambahkan jabat tangan SSL/TLS dan transmisi enkripsi data, yang juga termasuk dalam protokol lapisan aplikasi. Oleh karena itu, prinsip mempelajari protokol HTTPS akhirnya mempelajari protokol SSL/TLS.
Efek Protokol SSL/TLS
Komunikasi HTTP tanpa SSL/TLS bukanlah komunikasi yang dienkripsi.
1. Risiko menguping: Pihak ketiga dapat belajar tentang konten komunikasi.
2. Risiko Tampering: Pihak Ketiga dapat memodifikasi konten pemberitahuan.
3. Precurs Risiko: Pihak ketiga dapat berpura -pura menjadi identitas orang lain untuk berpartisipasi dalam komunikasi.
Protokol SSL/TLS dirancang untuk menyelesaikan tiga risiko ini.
1. Semua informasi adalah transmisi terenkripsi, dan pihak ketiga tidak dapat menguping.
2. Ada mekanisme verifikasi.
3. Dilengkapi dengan sertifikat ID untuk mencegah identitas disamar sebagai.
Proses operasi dasar
Gagasan dasar protokol SSL/TLS adalah menggunakan metode enkripsi kunci publik, yaitu, klien pertama -tama meminta kunci publik ke server, dan kemudian menggunakan kunci publik untuk informasi yang dienkripsi. , itu akan didekripsi dengan kunci pribadinya sendiri. Tetapi di sini Anda perlu memahami solusi untuk dua masalah.
1. Bagaimana memastikan bahwa kunci publik tidak dirusak?
Solusi: Tempatkan kunci publik dalam sertifikat digital. Selama sertifikat kredibel, kunci publik kredibel.
2. Jumlah enkripsi kunci publik terlalu besar, bagaimana mengurangi konsumsi waktu?
Solusi: Setiap dialog, sisi klien, dan server menghasilkan "kunci sesi" (kunci sesi) untuk mengenkripsi informasi. Karena "kunci dialog" adalah enkripsi simetris, kecepatan operasinya sangat cepat, dan kunci publik server hanya digunakan untuk mengenkripsi "kunci dialog" itu sendiri, yang mengurangi konsumsi waktu operasi terenkripsi.
Oleh karena itu, proses dasar protokol SSL/TLS adalah seperti ini:
1. Klien diminta ke server dan memverifikasi kunci publik.
2. Kedua belah pihak bernegosiasi dan menghasilkan "Kunci Dialog".
3. Kedua pihak menggunakan "kunci dialog" untuk melakukan komunikasi terenkripsi.
Dua kain pertama dalam proses di atas juga disebut "Tahap Jabat Tangan".
Proses terperinci dari tahap jabat tangan
"Tahap Handhake" melibatkan empat komunikasi.
Klien mengeluarkan permintaan (ClientHello)
Pertama -tama, klien (biasanya browser) mengirimkan permintaan komunikasi terenkripsi ke server, yang disebut permintaan klienhello. Pada langkah ini, klien terutama memberikan informasi berikut ke server:
1. Versi protokol yang didukung, seperti versi TLS 1.0
2. Angka acak yang dihasilkan oleh klien kemudian digunakan untuk menghasilkan "kunci dialog".
3. Metode enkripsi yang dapat didukung, seperti enkripsi kunci publik RSA.
4. Metode Kompresi Dukung.
Perlu dicatat bahwa informasi yang dikirim oleh klien tidak termasuk nama domain server. Dengan kata lain, server teoretis hanya dapat berisi satu situs web, jika tidak, itu tidak akan jelas di mana sertifikat digital dari situs web mana yang menyediakan klien. Inilah sebabnya mengapa server biasanya hanya memiliki satu sertifikat digital.
ServerHello
Setelah server menerima permintaan klien, ia menanggapi klien, yang disebut ServerHello. Respons server mencakup konten berikut:
1. Konfirmasikan versi protokol komunikasi terenkripsi, seperti versi TLS 1.0. Jika browser tidak konsisten dengan versi yang didukung oleh server, server mematikan komunikasi terenkripsi.
2. Angka acak yang dihasilkan oleh server kemudian digunakan untuk menghasilkan "Kunci Dialog".
3. Konfirmasikan metode enkripsi yang digunakan, seperti enkripsi kunci publik RSA.
4. Sertifikat server.
Selain informasi di atas, jika server perlu mengkonfirmasi identitas klien, itu akan mencakup permintaan lain, meminta klien untuk memberikan "sertifikat klien". Misalnya, lembaga keuangan seringkali hanya memungkinkan pelanggan bersertifikat untuk terhubung ke jaringan mereka sendiri dan akan memberikan kunci USB untuk pelanggan formal, yang berisi sertifikat klien.
Setelah klien menanggapi klien menerima respons server, sertifikat server terlebih dahulu memverifikasi server. Jika sertifikat tidak dikeluarkan oleh lembaga tepercaya, atau nama domain dalam sertifikat tidak konsisten dengan nama domain yang sebenarnya, atau sertifikat telah kedaluwarsa, itu akan menunjukkan peringatan kepada pengunjung, dan apakah akan terus berkomunikasi dari pilihan tersebut .
Jika tidak ada masalah dengan sertifikat, klien akan mengambil kunci publik dari sertifikat. Kemudian kirim tiga pesan berikut ke server.
1. Angka acak. Jumlah acak server dienkripsi untuk mencegah keran.
2. Kode Perubahan Pemberitahuan, menunjukkan bahwa informasi selanjutnya akan dikirim dengan metode enkripsi dan kunci yang disepakati oleh kedua belah pihak.
3. Jabat tangan klien mengakhiri pemberitahuan, menunjukkan bahwa tahap jabat tangan klien telah berakhir. Item ini biasanya merupakan nilai hash dari semua konten dari verifikasi server yang dikirim sebelumnya.
Angka acak pertama di atas adalah angka acak ketiga yang muncul di seluruh tahap jabat tangan, juga dikenal sebagai "kunci pra-master". Dengan itu, klien dan server memiliki tiga angka acak secara bersamaan, dan kemudian kedua pihak menggunakan metode enkripsi yang disepakati sebelumnya untuk menghasilkan "kunci sesi" yang sama yang digunakan dalam sesi.
Setelah server respons akhir server menerima kunci pra-master nomor acak ketiga dari klien, menghitung "kunci sesi" yang digunakan dalam sesi yang dihasilkan. Kemudian kirim informasi berikut ke klien.
1. Kode Perubahan Pemberitahuan, menunjukkan bahwa informasi selanjutnya akan dikirim dengan metode enkripsi dan kunci yang disepakati oleh kedua belah pihak.
2. Jabat tangan server mengakhiri pemberitahuan, menunjukkan bahwa tahap jabat tangan telah berakhir. Item ini juga merupakan nilai hash dari semua konten sebelumnya, yang digunakan untuk verifikasi klien.
Ujung jabat tangan
Pada titik ini, seluruh tahap jabat tangan sudah berakhir. Selanjutnya, klien dan server memasuki komunikasi terenkripsi, yang menggunakan protokol HTTP biasa, tetapi menggunakan konten enkripsi "kunci sesi".
Situs virtual server yang dibangun berdasarkan Nginx
Artikel sebelumnya diperkenalkan secara rinci cara menghasilkan sertifikat SSL di sisi server, dan membangun server HTTPS berdasarkan NGINX, tautan: Nginx membangun server HTTPS
Implementasi Komunikasi HTTPS Android
Karena berbagai alasan, gunakan kelas HTTPClicent untuk menjelaskan bagaimana Android membangun koneksi HTTPS. Demo kode adalah sebagai berikut.
MainActivity.java
paket com.example.photocrop; Client.httpclient; Impor Impor. Super.onCreate (SaveDInstanceState); ) {RunHTTPSConnecti on ();}}); httpstask.getStatus () == statushed) {httpstst ask = new createHtpsconnTask (); sBuffer = StringBuffer baru (); ); if (httpresponse! = null) {statusLine statusLine = httpresponse.getStatusLine (); (http response.getEntity (). getContent (), "UTF-8"); (Exception e) {log.e ("https", e.getMessage ()); ) {Log.e ("https", e.getMessage ());} akhirnya {} return null;} @Override void onpostexecute (void hasil) {if (! Textutils.isempty ()) {ContextView.setText (sBuffer .toString ());}}}}
Httputils.java
paket com.example.photocrop; Conn.scheme.scheme; .apache.params.basichtpparams; Newttppara MS (); eregistry (); ); ) {Basichtpparams Params = barichttpparams baru (); .register (skema baru ( "Http", plainsocketsocketsocketfactory (), 80); Httpclient getSpect (konteks konteks) {basichttpparams params = barichtpparams baru (); s, true); Schemeregistry () ;; }}
aktivitas_main.xml
<linearlayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com" android: lay out_width = "match_parent" android: tata letak_height = "Match_pareat" android: orientasi = "vertikal"> <tombol android: id = "@+id/create_button" android: tata letak_ "match_ parent" id: layout_height = "wrap_content" android: text = "@string/hello_world" android: "wrap_content" TextSize = "16sp" /> <textView android: id = "@+id /content_textView" android: layout_width = "match_parent" android: layout_height = "wra p_content" android: gravity = "center" android: textsize = "16sp" / /> </ Linearlayout>
Android menggunakan DEFAULTHTTPCLIENT untuk membuat koneksi HTTPS.
Schreg.register (skema baru ("https", sslsocketfactory.getsocketfactory (), 443));
Bergabunglah dengan dukungan HTTPS, Anda dapat secara efektif membuat koneksi HTTPS, seperti "https://www.google.com.hk", tetapi tidak mungkin untuk mengakses diri Anda berdasarkan server https yang dibangun oleh nginx, karena itu Tidak digunakan oleh sistem untuk digunakan oleh sistem.
Gunakan sertifikat khusus dan abaikan metode koneksi https yang diverifikasi
Metode penyelesaian sertifikat tidak dikenali oleh sistem adalah untuk melewatkan verifikasi sistem. Jika Anda ingin melewatkan verifikasi sistem, Anda tidak dapat lagi menggunakan socketFactory SSL standar sistem. Kemudian, untuk melewatkan verifikasi dalam socketFactory SSL khusus ini, Anda juga perlu menyesuaikan TrustManager, yang mengabaikan semua verifikasi, yaitu, TrustAll.
Paket Com.example.photocrop; Impor .xl.x509TrustManager; , Keymana GementException, KeyStorException, UnrecoverableKException {Super (TrustStore); X509TrustManager baru () {@Override public x509certified [] geta cceptedisSsuers () {return null;} @Override public void checksertrusted (x509certified [] rantai, string authtype) {} @override void void public void void (] x509 rantai {} @override public void void publiccrusted (x509 {} @override public void public void (x509 {override public void void (x509 ) Melempar CertificateException {}}; (Socket Socket, String Port, Boolean Autoclose) ion, UnknownHostException {return sslcontext.getSocketFactory (). );
Pada saat yang sama, Anda perlu memodifikasi metode register dari defaultTtpClient untuk mengubah ke sslsocket yang Anda bangun:
Publik httpclient getCustomClient () {barichtpparams params = barichttpparams baru () .register (skema baru ("http ", plainsocketfactory.getSocketFactory (), 80)); schreg.register (" httpsoc "Kectory.getSocketFactory (), 443)); clientConnectionManager connmgr baru -threadSafeclientConnManager (params, schreg); return baru defaulttpclient (params, schreg); return baru defaulttpclient (params); schreg); connArpClient (params); schreg); conn ConnAfconnManRMan (params, schreg); connArpClient (params, schreg); connAfeclient (params, schreg); connAfeclient (params, schreg);
Dengan cara ini, Anda dapat berhasil mengakses situs virtual HTTPS berbasis Nginx.
cacat:
Namun, meskipun solusi ini menggunakan HTTPS, konten komunikasi klien dan server dienkripsi, program mengendus tidak bisa mendapatkan konten transmisi, tetapi tidak dapat menahan "serangan perantara". Misalnya, konfigurasikan DNS di jaringan dalam, analisis nama domain server target ke alamat lokal, dan kemudian gunakan server menengah sebagai agen pada alamat ini. sertifikat. Dengan cara ini, semua konten komunikasi akan melewati agen ini, dan klien tidak akan memahami, yang disebabkan oleh sertifikat kunci publik server non -verifikasi klien.
Gunakan Sertifikat Kustom untuk membuat koneksi HTTPS
Untuk mencegah "serangan perantara" yang mungkin disebabkan oleh skema di atas, kami dapat mengunduh sertifikat kunci publik server, dan kemudian menyusun sertifikat kunci publik ke aplikasi Android untuk memverifikasi sertifikat dengan sendirinya.
Menghasilkan keystore
Untuk memverifikasi sertifikat kustom, pertama -tama kita harus menyusun sertifikat ke aplikasi. Sertifikat di sini mengacu pada kunci publik dari server target, yang dapat diperoleh dari file .crt atau file .pem yang dikonfigurasi oleh server web. Pada saat yang sama, Anda perlu mengkonfigurasi Bouundcastle.
Keytool -importcert -v -trustcacerts -alias contoh -file www.example.com.crt -keystore example.bks -storetype bks -providerclass rovider.boundcastleprovider -providerpath/home/wzy/unduhan/java/java/jdk1 .7.0_6 JRE/LIB/EXT/BCPROV-JDK16-145.JAR-STOREPASS PW123456
Setelah berjalan, konten sertifikat akan ditampilkan dan meminta Anda untuk mengonfirmasi apakah Anda dapat memasukkan Y Enter.
Setelah produksi file keystore berhasil, masukkan ke dalam direktori res/mentah aplikasi aplikasi.
Penggunaan keystore khusus untuk mengimplementasikan ide -ide koneksi mirip dengan Trushall.
Paket Com.example.photocrop; java.security.unrecoverableKeyException; Ablexception {super (trustStore);} Public SSLSocketFactory Context) {InputStream Input = NULL; ;} Catch (Exception e) {e.printstacktrace (); input = null;}}}}}}}}}}}}}
Pada saat yang sama, Anda perlu memodifikasi metode register dari defaultTtpClient untuk mengubah ke sslsocket yang Anda bangun:
Public HttpClient GetSpecilkeyStoreClient (konteks konteks) {barichttpparams params = barichttpparams baru (); Schemeregistry Schreg = Skemeregistry Baru ( ); Params);}}