Latar Belakang:
Saya sedang merancang skema otentikasi untuk layanan web REST. Ini tidak "benar-benar" perlu aman (ini lebih merupakan proyek pribadi) tetapi saya ingin membuatnya seaman mungkin sebagai pengalaman latihan / belajar. Saya tidak ingin menggunakan SSL karena saya tidak ingin kerumitan dan, sebagian besar, biaya pengaturannya.
Pertanyaan SO ini sangat berguna untuk memulai saya:
- Otentikasi tenang
- Praktik Terbaik untuk mengamankan REST API / layanan web
- Contoh API web SOAP / REST / RPC terbaik? Dan mengapa Anda menyukainya? Dan apa yang salah dengan mereka?
Saya sedang berpikir untuk menggunakan versi sederhana dari otentikasi Amazon S3 (saya suka OAuth tetapi tampaknya terlalu rumit untuk kebutuhan saya). Saya menambahkan nonce yang dibuat secara acak , disediakan oleh server, ke permintaan, untuk mencegah serangan replay.
Untuk sampai ke pertanyaan:
S3 dan OAuth bergantung pada penandatanganan URL permintaan bersama dengan beberapa header yang dipilih. Tak satu pun dari mereka menandatangani badan permintaan untuk permintaan POST atau PUT. Bukankah ini rentan terhadap serangan orang-di-tengah, yang menjaga url dan header dan menggantikan tubuh permintaan dengan data yang diinginkan penyerang?
Sepertinya saya bisa menjaga ini dengan memasukkan hash dari tubuh permintaan dalam string yang ditandatangani. Apakah ini aman?
Jawaban:
Jawaban sebelumnya hanya menyebutkan SSL dalam konteks transfer data dan sebenarnya tidak mencakup otentikasi.
Anda benar-benar bertanya tentang mengautentikasi klien REST API dengan aman. Kecuali Anda menggunakan otentikasi klien TLS, SSL saja BUKAN mekanisme otentikasi yang layak untuk API REST. SSL tanpa authc klien hanya mengotentikasi server , yang tidak relevan untuk sebagian besar API REST karena Anda benar-benar ingin mengautentikasi klien .
Jika Anda tidak menggunakan otentikasi klien TLS, Anda harus menggunakan sesuatu seperti skema otentikasi berbasis intisari (seperti skema kustom Amazon Web Service) atau OAuth 1.0a atau bahkan otentikasi HTTP Basic (tetapi hanya untuk SSL saja).
Skema ini mengotentikasi bahwa permintaan dikirim oleh seseorang yang diharapkan. TLS (SSL) (tanpa otentikasi klien) memastikan bahwa data yang dikirim melalui kabel tetap tidak teramplas. Mereka terpisah - tetapi saling melengkapi - perhatian.
Bagi mereka yang tertarik, saya telah memperluas pertanyaan SO tentang Skema Otentikasi HTTP dan cara kerjanya .
sumber
REST berarti bekerja dengan standar web, dan standar untuk transfer "aman" di web adalah SSL. Hal lain akan menjadi agak funky dan membutuhkan upaya penyebaran tambahan untuk klien, yang harus memiliki perpustakaan enkripsi yang tersedia.
Setelah Anda berkomitmen ke SSL, pada prinsipnya tidak ada yang diperlukan untuk otentikasi. Anda dapat kembali menggunakan standar web dan menggunakan HTTP Basic auth (nama pengguna dan token rahasia yang dikirimkan bersama dengan setiap permintaan) karena jauh lebih sederhana daripada protokol penandatanganan yang rumit, dan masih efektif dalam konteks koneksi yang aman. Anda hanya perlu memastikan kata sandi tidak pernah melampaui teks biasa; jadi jika kata sandi tersebut pernah diterima melalui koneksi teks biasa, Anda bahkan dapat menonaktifkan kata sandi dan mengirimkan email kepada pengembang. Anda juga harus memastikan kredensial tidak dicatat di mana pun setelah diterima, sama seperti Anda tidak akan mencatat kata sandi biasa.
HTTP Digest adalah pendekatan yang lebih aman karena mencegah token rahasia yang diteruskan; alih-alih, ini adalah hash yang dapat diverifikasi server di ujung lainnya. Meskipun mungkin berlebihan untuk aplikasi yang kurang sensitif jika Anda telah mengambil tindakan pencegahan yang disebutkan di atas. Lagipula, kata sandi pengguna sudah dikirim dalam teks biasa ketika mereka masuk (kecuali jika Anda melakukan enkripsi JavaScript yang bagus di browser), dan juga cookie mereka pada setiap permintaan.
Perhatikan bahwa dengan API, lebih baik bagi klien untuk melewati token - string yang dibuat secara acak - daripada kata sandi yang dibuat oleh pengembang untuk masuk ke situs web. Jadi pengembang harus dapat masuk ke situs Anda dan menghasilkan token baru yang dapat digunakan untuk verifikasi API.
Alasan utama untuk menggunakan token adalah bahwa token dapat diganti jika dikompromikan, sedangkan jika kata sandi dikompromikan, pemilik dapat masuk ke akun pengembang dan melakukan apa pun yang mereka inginkan dengannya. Keuntungan lebih lanjut dari token adalah Anda dapat mengeluarkan beberapa token ke pengembang yang sama. Mungkin karena mereka memiliki beberapa aplikasi atau karena mereka ingin token dengan tingkat akses yang berbeda.
(Diperbarui untuk mencakup implikasi membuat koneksi hanya SSL.)
sumber
Atau Anda bisa menggunakan solusi yang diketahui untuk masalah ini dan menggunakan SSL. Sertifikat yang ditandatangani sendiri bebas dan ini proyek pribadi, kan?
sumber
Jika Anda memerlukan hash body sebagai salah satu parameter dalam URL dan URL itu ditandatangani melalui kunci pribadi, maka serangan man-in-the-middle hanya akan dapat menggantikan tubuh dengan konten yang akan menghasilkan hash yang sama. Mudah dilakukan dengan nilai hash MD5 sekarang setidaknya dan ketika SHA-1 rusak, Anda mendapatkan gambar.
Untuk mengamankan tubuh dari gangguan, Anda harus memerlukan tanda tangan dari tubuh, yang kemungkinan serangannya tidak dapat dilakukan karena serangan dari orang yang berada di tengah tidak akan mengetahui kunci pribadi yang menghasilkan tanda tangan tersebut. .
sumber
Bahkan, S3 auth asli tidak memungkinkan untuk konten yang akan ditandatangani, meskipun dengan tanda tangan MD5 lemah. Anda cukup menerapkan praktik opsional mereka termasuk header Content-MD5 dalam HMAC (string yang akan ditandatangani).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Skema otentikasi v4 baru mereka lebih aman.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
sumber
Ingatlah bahwa saran Anda mempersulit klien untuk berkomunikasi dengan server. Mereka perlu memahami solusi inovatif Anda dan mengenkripsi data yang sesuai, model ini tidak begitu baik untuk API publik (kecuali jika Anda amazon \ yahoo \ google ..).
Bagaimanapun, jika Anda harus mengenkripsi konten tubuh saya sarankan Anda untuk memeriksa standar dan solusi yang ada seperti:
Enkripsi XML (standar W3C)
Keamanan XML
sumber