Praktik terbaik seputar pembuatan token OAuth?

100

Saya menyadari bahwa spesifikasi OAuth tidak menentukan apa pun tentang asal kode ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret, atau Verifier, tetapi saya ingin tahu apakah ada praktik terbaik untuk membuat token yang sangat aman (terutama Token / Kombinasi rahasia).

Seperti yang saya lihat, ada beberapa pendekatan untuk membuat token:

  1. Cukup gunakan byte acak, simpan di DB yang terkait dengan konsumen / pengguna
  2. Hash beberapa data khusus pengguna / konsumen, simpan di DB yang terkait dengan konsumen / pengguna
  3. Enkripsi data khusus pengguna / konsumen

Keuntungan dari (1) adalah database adalah satu-satunya sumber informasi yang tampaknya paling aman. Akan lebih sulit untuk menjalankan serangan daripada (2) atau (3).

Hashing data nyata (2) akan memungkinkan pembuatan kembali token dari data yang mungkin sudah diketahui. Mungkin tidak benar-benar memberikan keuntungan apa pun untuk (1) karena tetap perlu menyimpan / mencari. Lebih intensif CPU daripada (1).

Mengenkripsi data nyata (3) akan memungkinkan penguraian sandi untuk mengetahui informasi. Ini akan membutuhkan lebih sedikit penyimpanan & kemungkinan pencarian lebih sedikit daripada (1) & (2), tetapi berpotensi kurang aman juga.

Apakah ada pendekatan / keuntungan / kerugian lain yang harus dipertimbangkan?

EDIT: pertimbangan lain adalah HARUS ada semacam nilai acak dalam Token karena harus ada kemampuan untuk kedaluwarsa dan menerbitkan ulang token baru sehingga tidak boleh hanya terdiri dari data nyata.

Ikuti Pertanyaan :

Apakah ada panjang Token minimum untuk membuat aman secara kriptografis? Seperti yang saya pahami, Rahasia Token yang lebih lama akan membuat tanda tangan yang lebih aman. Apakah pemahaman ini benar?

Apakah ada keuntungan menggunakan pengkodean tertentu dibandingkan yang lain dari perspektif hashing? Misalnya, saya melihat banyak API menggunakan pengkodean hex (misalnya string GUID). Dalam algoritme penandatanganan OAuth, Token digunakan sebagai string. Dengan string hex, kumpulan karakter yang tersedia akan jauh lebih kecil (lebih dapat diprediksi) daripada yang dikatakan dengan pengkodean Base64. Tampak bagi saya bahwa untuk dua string dengan panjang yang sama, string dengan himpunan karakter yang lebih besar akan memiliki distribusi hash yang lebih baik / lebih luas. Menurut saya ini akan meningkatkan keamanan. Apakah asumsi ini benar?

Spesifikasi OAuth mengangkat masalah ini di 11.10 Entropy of Secrets .

mckamey
sumber
Mengapa enkripsi? Bukankah hashing cukup baik? Jika hashing saja sudah cukup baik untuk kata sandi, bukankah seharusnya lebih baik untuk token akses yang lebih lama?
AlikElzin-kilaka
Sudah 7,5 tahun sejak saya mengajukan pertanyaan itu. Sejujurnya saya tidak ingat.
mckamey
1
Membaca lagi, hashing dan enkripsi adalah dua pendekatan berbeda yang disarankan. Enkripsi akan memungkinkan server mendapatkan beberapa info tanpa pencarian DB. Itu adalah salah satu pertukaran di antara banyak lainnya.
mckamey

Jawaban:

93

OAuth tidak mengatakan apa-apa tentang token kecuali bahwa ia memiliki rahasia yang terkait dengannya. Jadi semua skema yang Anda sebutkan akan berhasil. Token kami berkembang seiring bertambahnya situs. Ini adalah versi yang kami gunakan sebelumnya,

  1. Token pertama kita adalah BLOB terenkripsi dengan nama pengguna, rahasia token dan kedaluwarsa, dll. Masalahnya adalah kita tidak dapat mencabut token tanpa catatan apa pun pada host.

  2. Jadi kami mengubahnya untuk menyimpan semuanya di database dan token hanyalah nomor acak yang digunakan sebagai kunci database. Ini memiliki indeks nama pengguna sehingga mudah untuk membuat daftar semua token untuk pengguna dan mencabutnya.

  3. Kami mendapatkan cukup sedikit aktivitas peretasan. Dengan nomor acak, kita harus pergi ke database untuk mengetahui apakah token itu valid. Jadi kami kembali ke BLOB terenkripsi lagi. Kali ini, token hanya berisi nilai terenkripsi dari kunci dan kedaluwarsa. Jadi kami dapat mendeteksi token yang tidak valid atau kedaluwarsa tanpa membuka database.

Beberapa detail implementasi yang dapat membantu Anda,

  1. Tambahkan versi dalam token sehingga Anda dapat mengubah format token tanpa merusak yang sudah ada. Semua token kami memiliki byte pertama sebagai versi.
  2. Gunakan versi aman URL dari Base64 untuk menyandikan BLOB sehingga Anda tidak perlu berurusan dengan masalah pengkodean URL, yang membuat debugging lebih sulit dengan tanda tangan OAuth, karena Anda mungkin melihat basestring yang dienkode tiga kali.
ZZ Coder
sumber
2
Luar biasa, terima kasih. Ide versi itu bagus. Saya menggunakan Base64 yang ramah-URL, tetapi saya berharap saya memiliki pengkodean alfa-numerik yang ketat untuk membaca lebih mudah.
mckamey
Belum pernah terpikir sebelumnya, sangat menarik! Saya berencana menggunakan cache kunci APC untuk menjaga beban yang tidak dapat diakses dari DB sebelum saya membaca ini. Masih tidak yakin apakah ini mungkin tidak lebih lambat dari APC pencarian memori bersama (setidaknya pada permintaan ke-2, ke-3, dll ... dalam rentang waktu yang wajar).
Philzen