Bagaimana cara memastikan REST API saya hanya menanggapi permintaan yang dihasilkan oleh klien tepercaya, dalam kasus saya aplikasi seluler saya sendiri? Saya ingin mencegah permintaan yang tidak diinginkan datang dari sumber lain. Saya tidak ingin pengguna mengisi kunci serial atau apa pun, itu harus terjadi di belakang layar, pada saat pemasangan, dan tanpa interaksi pengguna apa pun.
Sejauh yang saya tahu, HTTPS hanya untuk memvalidasi server yang Anda ajak berkomunikasi adalah yang dikatakannya. Saya tentu saja akan menggunakan HTTPS untuk mengenkripsi data.
Apakah ada cara untuk menyelesaikan ini?
Pembaruan: Pengguna dapat melakukan tindakan hanya baca, yang tidak mengharuskan pengguna untuk login, tetapi mereka juga dapat melakukan tindakan menulis, yang memang mengharuskan pengguna untuk login (Otentikasi oleh Token Akses). Dalam kedua kasus ini saya ingin API menanggapi permintaan yang datang hanya dari aplikasi seluler tepercaya.
API juga akan digunakan untuk mendaftarkan akun baru melalui aplikasi seluler.
Pembaruan 2: Sepertinya ada beberapa jawaban untuk ini, tapi sejujurnya saya tidak tahu yang mana yang ditandai sebagai jawaban. Ada yang bilang itu bisa dilakukan, ada yang bilang tidak bisa.
Jawaban:
Kamu tidak bisa
Anda tidak pernah dapat memverifikasi suatu entitas, entitas apa pun , baik itu orang, klien perangkat keras atau klien perangkat lunak. Anda hanya dapat memverifikasi bahwa apa yang mereka katakan adalah benar, lalu anggap jujur .
Misalnya, bagaimana Google tahu saya masuk ke akun Gmail saya? Mereka hanya meminta saya untuk nama pengguna dan kata sandi, memverifikasi itu , lalu menganggap kejujuran karena siapa lagi yang akan mendapatkan info itu? Pada titik tertentu Google memutuskan bahwa ini tidak cukup dan menambahkan verifikasi perilaku (mencari perilaku aneh) tetapi itu masih mengandalkan orang tersebut untuk melakukan perilaku tersebut , kemudian memvalidasi perilaku tersebut .
Ini persis sama dengan memvalidasi Klien. Anda hanya dapat memvalidasi perilaku Klien, tetapi bukan Klien itu sendiri.
Jadi dengan SSL, Anda dapat memverifikasi bahwa Klien memiliki sertifikat yang valid atau tidak, Jadi seseorang dapat menginstal Aplikasi Anda, mendapatkan Cert, lalu menjalankan semua kode baru.
Jadi pertanyaannya adalah: Mengapa ini begitu kritis? Jika ini merupakan masalah nyata, saya akan mempertanyakan pilihan Anda untuk klien yang gemuk. Mungkin Anda harus menggunakan Aplikasi web (jadi Anda tidak perlu membuka API Anda).
Lihat juga: Mengalahkan Validasi Sertifikat SSL untuk Aplikasi Android
dan: Seberapa amankah sertifikat SSL klien di aplikasi seluler?
sumber
Saya yakin Anda merasa nyaman dengan berurusan dengan login pengguna, dan dengan komunikasi melalui SSL, jadi saya akan fokus pada apa yang saya pikir itu bagian yang lebih menarik dari pertanyaan: bagaimana memastikan bahwa tindakan read-only Anda - yang tidak mengharuskan pengguna untuk diautentikasi - hanya diterima dari aplikasi klien Anda sendiri?
Sebelum hal lain, ada kelemahan yang mengisyaratkan fNek dalam jawaban sebelumnya - aplikasi klien Anda ada di tangan pengguna yang berpotensi bermusuhan. Mereka dapat diperiksa, komunikasi mereka diinspeksi, kode mereka dibongkar. Tidak ada yang akan saya sarankan akan memungkinkan Anda untuk menjamin bahwa seseorang tidak merekayasa balik klien Anda dan menyalahgunakan REST API Anda. Tapi itu harus menempatkan penghalang di depan upaya kasual.
Bagaimanapun, pendekatan umum adalah:
misalnya, bayangkan
GET
permintaan/products/widgets
Katakanlah rahasia klien adalah "OH_HAI_I_IZ_SECRET"
Menggabungkan kata kerja HTTP, dan URL, dan rahasia:
Dan ambil hash SHA-1 itu:
Kemudian kirimkan, jadi permintaannya adalah untuk:
Terakhir, untuk mencegah seseorang dari setidaknya mengulangi permintaan individual, ambil juga stempel waktu, dan tambahkan itu ke parameter dan hash. mis. saat ini, dalam waktu Unix, adalah 1384987891. Tambahkan itu ke rangkaian:
Hash itu:
Dan kirim:
Server akan memeriksa hash dan juga memverifikasi bahwa cap waktu terkini (mis. Dalam waktu 5 menit untuk memungkinkan jam tidak sinkron dengan sempurna)
Peringatan! Karena Anda berbicara tentang aplikasi seluler, ada risiko pasti bahwa telepon seseorang akan salah jam. Atau zona waktu salah. Atau sesuatu. Menambahkan waktu ke hash mungkin akan merusak beberapa pengguna yang sah, jadi gunakan ide itu dengan hati-hati.
sumber
Bagi siapa pun yang tertarik, di Android Anda BISA memverifikasi bahwa permintaan yang Anda dapatkan telah dikirim dari aplikasi Anda.
Singkatnya, ketika Anda mengunggah aplikasi ke Google, Anda menandatanganinya, dengan kunci unik yang hanya diketahui oleh Anda (dan google).
Proses verifikasi berjalan (ish) seperti ini:
blog lengkap yang menjelaskannya dan cara menerapkannya dapat ditemukan di sini: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html
sumber
Ok, jadi nilainya menyebutkan sebelum saya memulai bahwa untuk sebagian besar aplikasi ini sangat berlebihan. Untuk sebagian besar kasus penggunaan, hanya memiliki satu sertifikat dan / atau token yang valid lebih dari cukup. Jika itu melibatkan melakukan sesuatu yang sulit seperti mendekompilasi aplikasi Anda, maka sebagian besar peretas tidak akan repot kecuali Anda memberikan beberapa data yang sangat berharga. Tapi hei, apakah kesenangan dalam jawaban itu?
Jadi yang dapat Anda lakukan adalah mengatur kriptografi asimetris seperti tanda tangan digital yang digunakan untuk menandatangani program. Setiap aplikasi kemudian dapat memiliki sertifikat individual yang dikeluarkan oleh CA tunggal dan diverifikasi ketika pengguna Anda terhubung. (baik saat pertama kali mendaftar atau saat pertama kali menginstal) Saat sertifikat itu diautentikasi, Anda kemudian dapat mengamankan aplikasi Anda dengan mendaftarkan sertifikat tersebut sebagai valid untuk satu pengenal perangkat yang diberikan (seperti Android ID )
sumber
Seperti yang disebutkan @Morons dalam jawabannya, sangat sulit untuk memverifikasi entitas di ujung koneksi yang lain.
Cara paling sederhana untuk memberikan tingkat keaslian adalah dengan meminta server memeriksa beberapa rahasia yang hanya diketahui oleh entitas nyata. Untuk pengguna, itu bisa berupa nama pengguna dan kata sandi. Untuk perangkat lunak di mana tidak ada pengguna, Anda mungkin menanamkan rahasia.
Masalah dengan pendekatan ini adalah Anda harus menaruh kepercayaan pada klien. Jika seseorang membalikkan rekayasa aplikasi Anda atau mencuri kata sandi Anda, mereka dapat berpura-pura menjadi Anda.
Anda dapat mengambil langkah-langkah untuk membuatnya lebih sulit untuk mengekstrak informasi rahasia dengan mengaburkannya di executable. Alat seperti ProGuard yang merupakan obfuscator untuk Java dapat membantu dengan ini, saya tidak tahu banyak tentang kebingungan dalam bahasa lain tetapi ada kemungkinan alat serupa. Menggunakan koneksi TLS membantu mencegah orang mengintip lalu lintas Anda, tetapi tidak mencegah serangan MITM. Pinning dapat membantu mengatasi masalah itu.
Saya bekerja untuk perusahaan bernama CriticalBlue (Pengungkapan penuh!) Yang memiliki produk bernama Approov yang mencoba mengatasi masalah kepercayaan ini. Ini berfungsi untuk Android / iOS saat ini dan menyediakan mekanisme bagi server kami untuk memeriksa integritas aplikasi klien. Ini dilakukan dengan meminta klien menghitung respons terhadap tantangan acak. Klien harus menghitung respons menggunakan atribut dari paket aplikasi yang diinstal yang sulit dipalsukan dan itu mencakup beberapa mekanisme anti-tamper canggih.
Ini mengembalikan token yang kemudian dapat Anda kirim sebagai bukti keaslian ke API Anda.
Perbedaan penting dengan pendekatan ini adalah bahwa meskipun mungkin untuk menonaktifkan pemeriksaan keaslian pada klien, jika Anda melakukannya Anda tidak akan mendapatkan token otentikasi Anda perlu memverifikasi aplikasi Anda dengan server. Pustaka juga sangat erat dengan karakteristik executable yang ada di dalamnya, sehingga akan sangat sulit untuk menanamkannya di aplikasi palsu dan membuatnya bekerja.
Ada analisis biaya / manfaat yang harus dibuat oleh pengembang API untuk memutuskan seberapa besar kemungkinan seseorang akan mencoba meretas API mereka dan seberapa mahal harganya. Pemeriksaan rahasia sederhana dalam aplikasi mencegah serangan sepele, tetapi untuk melindungi diri Anda dari penyerang yang lebih gigih mungkin jauh lebih rumit dan berpotensi mahal.
sumber
SSL akan mengamankan saluran komunikasi.
Login yang berhasil akan mengeluarkan token otentikasi melalui koneksi terenkripsi.
Token otentikasi akan diteruskan ke API REST Anda di semua permintaan berikutnya.
sumber
Itu tidak akan terlalu aman, tetapi Anda dapat menambahkan semacam kode rahasia atau bahkan tanda tangan dgital. Kelemahan: Ini harus dimasukkan dalam aplikasi, yang membuatnya mudah untuk mendapatkannya jika Anda tahu apa yang Anda lakukan.
sumber
Bahkan, Anda dapat menggunakan SSL untuk mengotentikasi klien dan server. Atau, dengan kata lain, "Ya, Anda dapat menggunakan sertifikat klien".
Anda harus ...
Anda dapat meminta aplikasi seluler menyimpan sertifikat di mana pun Anda inginkan. Karena Anda menginginkannya otentikasi khusus aplikasi, Anda harus mempertimbangkan untuk menyimpan sertifikat di lokasi disk yang dilindungi (di Android, Anda dapat membuat tabel "config" dalam database SQLite Anda, dan satu baris untuk sertifikat Anda dan satu lagi untuk kunci pribadi Anda) .
sumber