Pembuat token acak

Menghasilkan rahasia dari CSPRNG browser — heksadesimal, base64url, atau alfabet khusus, plus frasa-sandi diceware EFF — dengan entropi dalam bit.

Membuat…
Entropi192.0 bit

Waktu rata-rata untuk menemukannya, pada tiga laju tebakan. Sebaran di antaranya lebih besar daripada perbedaan apa pun yang dibuat rahasianya sendiri.

  • Terhadap login yang membatasi laju — 10 tebakan/dtk10^49 tahun
  • Terhadap hash lambat yang bocor (bcrypt, argon2) — 10⁴/dtk10^46 tahun
  • Terhadap hash cepat yang bocor (SHA-256, MD5) — 10¹²/dtk10^38 tahun

Mengambil dari 64 karakter, jadi masing-masing membawa 6.00 bit.

Apa yang dilakukan alat ini

Ia menghasilkan rahasia: nilai yang satu-satunya pertahanannya adalah tak ada yang bisa menebaknya. Pilih sebuah alfabet dan sebuah panjang untuk sebuah kunci API atau sandi basis data, atau beralih ke sebuah frasa-sandi yang diambil dari sebuah daftar kata terbitan untuk sesuatu yang harus diketik seseorang. Setiap hasil dihasilkan di browser Anda dan ditampilkan dengan satu angka yang menjelaskan kekuatannya dengan jujur.

Ini adalah pekerjaan berbeda dari pembangkit UUID di situs ini. Sebuah UUID harus unik, sehingga dua catatan tak pernah bertumbukan; sebuah rahasia harus tak-tertebak, yang merupakan syarat yang lebih kuat dan kegagalan yang berbeda. Sebuah pengenal yang dapat diprediksi tak berbahaya. Sebuah rahasia yang dapat diprediksi adalah pintu terbuka.

Dari mana keacakan datang

Semuanya di sini mengambil dari crypto.getRandomValues, pembangkit acak browser yang aman secara kriptografis, yang dibenihi dari kolam entropi sistem operasi — sumber yang sama yang dipakai openssl rand dan /dev/urandom.

Alternatifnya, Math.random, bukan sebuah fungsi keamanan dan tak pernah mengklaim menjadi begitu. Ia adalah pembangkit pseudo-acak yang cepat dengan sebuah keadaan internal kecil, dan di setiap mesin saat ini keadaan itu bisa dipulihkan dari sebuah rangkaian pendek keluaran, setelahnya setiap nilai lalu dan mendatang diketahui. Sebuah token yang dibangun darinya tampak persis seacak yang nyata; perbedaannya hanya muncul ketika seseorang repot melihat.

Sebuah pertanyaan yang masuk akal adalah apakah sebuah halaman web adalah tempat yang tepat untuk menghasilkan sebuah rahasia produksi sama sekali. Pembangkitannya sendiri kukuh: ia adalah CSPRNG platform, halamannya statis, dan tak ada yang dikirim. Bagian yang layak dipikirkan adalah yang di sekitarnya — sebuah rahasia yang melewati papan-klip bisa dibaca aplikasi lain, dan yang ditempel ke sebuah terminal biasanya mendarat di riwayat shell. Itu adalah pertimbangan yang sama dengan metode lain mana pun.

Bias yang bersembunyi dalam implementasi yang jelas

Mengubah bita acak menjadi karakter tampak seperti satu baris: ambil sebuah bita, ambil ia modulo ukuran alfabet, indeks ke dalam alfabet. Ia secara halus salah untuk setiap alfabet yang ukurannya tak membagi 256 secara rata, dan keluaran tak memberi tanda darinya.

Dengan 62 karakter alfanumerik, 256 tak membagi secara rata: 62 masuk ke 256 empat kali dengan 8 tersisa. Kedelapan nilai bita sisa itu — 248 sampai 255 — melipat kembali ke 8 karakter pertama alfabet, jadi masing-masing dari itu mendapat lima peluang dari 256 sementara sisanya mendapat empat. Kedelapan karakter pertama sekitar 25% lebih mungkin daripada yang lain.

Perbaikannya adalah pengambilan-penolakan: buang sebuah pengambilan yang mendarat di ekor sisa dan ambil lagi, ketimbang melipatnya kembali. Ia menelan sekitar satu pengambilan ekstra dalam tiga puluh dua untuk sebuah alfabet 62-karakter dan tak sama sekali untuk heksadesimal atau base64url, yang ukurannya adalah pangkat dua dan karenanya tak punya ekor. Alat ini menolak; efeknya tak terlihat dalam token tunggal mana pun, yang persis mengapa ia layak dinyatakan.

Entropi, yang adalah satu-satunya ukuran jujur

Entropi dalam bit mengatakan seberapa besar ruang rahasia yang sama-sama mungkin: n bit berarti 2^n kemungkinan. Ia aditif dan mudah dibandingkan, dan ia tak mengatakan apa pun tentang seberapa cepat siapa pun bisa mencari ruang itu — yang merupakan sebuah fitur, karena bagian itu bergantung pada hal yang tak bisa diketahui sebuah pembangkit.

Aritmetikanya sengaja sederhana. Setiap karakter menyumbang log2(ukuran alfabet) bit, dan setiap kata menyumbang log2(ukuran daftar kata), jadi:

  • Sebuah karakter heksadesimal adalah 4 bit, jadi sebuah token heksadesimal 32-karakter persis 128 bit — sebuah kunci AES-128 yang ditulis penuh.
  • Sebuah karakter base64url adalah 6 bit, jadi 22 karakter melewati 128 bit dan 43 melewati 256.
  • Sebuah karakter alfanumerik sekitar 5,95 bit; mengecualikan yang mirip-rupa menjatuhkan alfabet ke 58 dan karakter ke 5,86, yang menelan kira-kira satu karakter panjang setiap dua belas.
  • Sebuah kata dari daftar panjang EFF adalah 12,925 bit, karena daftar punya 7776 entri, yaitu 6^5 — lima lemparan dadu.
  • Sebuah kata dari daftar pendek EFF adalah 10,34 bit, dari 1296 entri, yaitu 6^4.

Sebuah target umum adalah 128 bit, yang adalah tempat brute force berhenti menjadi sebuah strategi ketimbang sekadar mahal. Itu adalah 32 karakter heksadesimal, 22 karakter base64url, atau 10 kata dari daftar panjang EFF.

Mengapa tak ada satu "waktu untuk memecahkan"

Sebuah rahasia tak punya sebuah waktu pemecahan. Pasangan sebuah rahasia dan apa pun yang menjaganya punya satu, dan penjaga itu jauh lebih penting daripada rahasianya. Nilai yang sama yang akan memakan lebih lama daripada umur alam semesta untuk ditemukan melalui sebuah formulir login jatuh dalam satu sore jika ia disimpan sebagai sebuah SHA-256 tanpa-salt dan basis data bocor.

Jadi tiga laju ditampilkan ketimbang satu angka, dan masing-masing dinamai:

  • Sepuluh tebakan sedetik, terhadap sebuah login yang membatasi laju. Ini adalah plafon realistis untuk seorang penyerang yang harus melewati layanan Anda.
  • Sepuluh ribu tebakan sedetik, terhadap sebuah hash sandi bocor yang dibangun agar lambat — bcrypt pada biaya modern, atau argon2. Kelambatan adalah seluruh inti fungsi itu.
  • Satu triliun tebakan sedetik, terhadap sebuah hash bocor yang tak pernah dimaksudkan untuk sandi. SHA-256 dan MD5 dirancang agar cepat, dan sebuah rig GPU memang sangat cepat.

Laju dibulatkan ke pangkat sepuluh secara sengaja. Apa pun yang lebih presisi akan menyarankan sebuah pengukuran satu penyerang tertentu, ketika informasi yang berguna adalah sebelas orde besaran antara baris pertama dan terakhir. Jika sebuah rahasia nyaman di ketiganya, pertanyaan terselesaikan tanpa perlu angka pastinya.

Setiap angka adalah rata-rata, yang adalah setengah ruang ketimbang seluruhnya — sebuah pencarian menemukan jawaban di tengah jalan rata-rata. Dan melampaui sejuta tahun jawaban diberikan sebagai sebuah orde besaran, karena "empat ratus triliun tahun" bukan sebuah durasi yang siapa pun bisa membandingkan. Alam semesta berusia sekitar 10^10 tahun, yang menjadi jangkar berguna untuk baris yang menjangkau sejauh itu.

Frasa-sandi, dan dari mana kekuatannya sebenarnya datang

Sebuah frasa-sandi kuat karena persis satu alasan: beberapa kata dipilih secara acak dari sebuah daftar besar. Ia tak kuat karena ia panjang, dan ia tak kuat karena ia tampak seperti bahasa. Enam kata acak dari sebuah daftar 7776-kata sekitar 77 bit; enam kata yang seseorang pikirkan bernilai jauh lebih sedikit, karena orang tak memilih secara seragam dan seorang penyerang tahu hal yang sama tentang frasa umum yang Anda tahu.

Kedua daftar di sini datang dari EFF dan adalah daftar diceware terbitan, diunduh tanpa perubahan. Mereka bukan daftar yang dirakit di sini, dan itu penting: sebuah daftar kata yang seseorang ciptakan punya ukuran tak diketahui, tumpang-tindih tak diketahui dengan daftar lain, dan tak ada cara memeriksa klaim entropi yang dibuat tentangnya.

  • Daftar panjang punya 7776 kata, satu untuk setiap lemparan lima dadu, dan memberi 12,925 bit per kata.
  • Daftar pendek punya 1296 kata, satu untuk setiap lemparan empat dadu, dan memberi 10,34 bit per kata. Kata-katanya lebih pendek — tak ada yang lebih dari lima huruf — yang membuatnya lebih mudah diketik dengan biaya butuh lebih banyak kata untuk kekuatan yang sama.

Sebuah kata yang berulang dalam sebuah frasa-sandi bukan sebuah cacat dan tak dihasilkan ulang di sini. Setiap pengambilan mandiri, jadi pasangan kata tertentu mana pun persis sama mungkinnya dengan yang lain; menolak pengulangan akan menyusutkan ruang frasa-sandi yang mungkin dan membuatnya sedikit lebih lemah, bukan lebih kuat.

Kedua daftar EFF mengandung segelintir entri bertanda-hubung — t-shirt, yo-yo, drop-down, felt-tip. Jika pemisahnya juga sebuah tanda hubung, sebuah frasa-sandi yang mengandung salah satunya tak bisa dipecah kembali menjadi kata-katanya tanpa ambigu. Ia adalah masalah tampilan ketimbang keamanan, dan memilih sebuah spasi atau sebuah titik sebagai pemisah menghindarinya sepenuhnya.

Opsi yang menelan entropi, dan yang tidak

Mengecualikan karakter mirip-rupa menukar kekuatan demi keterbacaan, dan tukarnya terlihat. Membuang 0, O, I, dan l mengambil alfabet alfanumerik dari 62 karakter ke 58 — yang, persis, alfabet base58 yang dipakai Bitcoin, dan karena alasan yang sama. Setiap karakter jatuh dari 5,95 ke 5,86 bit, jadi sebuah token butuh sekitar satu karakter ekstra setiap dua belas untuk tetap sekuat itu. Itu biasanya sepadan untuk apa pun yang akan seseorang baca dari sebuah layar dan ketik di tempat lain.

Opsi ditawarkan hanya di tempat ia berarti sesuatu. Heksadesimal dan base64url adalah pengodean, bukan kumpulan karakter: alfabetnya ditetapkan oleh sebuah spesifikasi, dan heksadesimal tanpa 0 bukan heksadesimal lagi — tak ada yang bisa mendekodenya.

Mengapitalkan tiap kata dari sebuah frasa-sandi tak menambah apa pun sama sekali, dan angka kekuatan di sini secara sengaja tak bergerak ketika Anda menyalakannya. Ia adalah transformasi yang sama diterapkan setiap kali, jadi ia tak menciptakan satu kemungkinan baru pun: seorang penyerang yang tahu frasanya dikapitalkan persis di tempat mereka mulai. Opsi ada karena bidang sandi masih menuntut sebuah huruf kapital, bukan karena ia membantu.

Memilih sebuah panjang

Untuk apa pun yang ditangani sebuah mesin — kunci API, token sesi, rahasia webhook, sandi basis data — tak ada alasan untuk berhemat. 32 karakter heksadesimal atau 22 karakter base64url memberi 128 bit, dan melangkah lebih jauh hanya menelan bita dalam sebuah berkas konfigurasi.

Untuk apa pun yang diketik seseorang, kendalanya berbeda dan sebuah frasa-sandi biasanya bentuk yang lebih baik. Enam kata dari daftar panjang lebih kuat daripada sebuah sandi acak dua-belas-karakter dan jauh lebih mudah dibenarkan pada percobaan pertama, yang lebih penting daripada kedengarannya: sebuah rahasia yang orang salah ketik adalah sebuah rahasia yang orang tuliskan.

Untuk sebuah kode numerik pembacaan jujurnya adalah empat digit adalah 13 bit dan bisa dihabiskan dalam detik oleh apa pun yang tak membatasi laju. Sebuah PIN hanya pernah aman karena kebijakan penguncian di sekitarnya, tak pernah karena kekuatannya sendiri.

Pertanyaan yang sering diajukan

Berapa panjang sebuah kunci API seharusnya?
Bidik 128 bit entropi atau lebih, yang adalah tempat brute force berhenti menjadi sebuah strategi. Itu adalah 32 karakter heksadesimal, 22 karakter base64url, atau 43 karakter base64url jika Anda menginginkan 256 bit. Untuk sebuah nilai yang hanya perangkat lunak yang menanganinya, opsi yang lebih panjang tak menelan apa pun.
Apakah ini lebih aman daripada menghasilkan sebuah rahasia dengan Math.random?
Ya, dan perbedaannya bukan soal tingkat. Math.random adalah pembangkit pseudo-acak dengan sebuah keadaan kecil yang mesin saat ini memungkinkannya dipulihkan dari sebuah rangkaian pendek keluaran, setelahnya setiap nilai yang akan pernah dihasilkannya diketahui. Alat ini memakai crypto.getRandomValues, CSPRNG platform, yang adalah sumber yang sama yang diambil openssl rand.
Mengapa Anda tak menampilkan satu "waktu untuk memecahkan"?
Karena tak ada angka semacam itu. Rahasia yang sama tak terjangkau di balik sebuah login yang membatasi laju dan jatuh cepat di balik sebuah hash cepat yang bocor — sebelas orde besaran berjarak. Sebuah angka tunggal harus memilih satu asumsi lalu menyembunyikannya, dan pembaca mengingat angkanya ketimbang asumsinya. Tiga laju bernama menaruh asumsi di tempat Anda bisa melihatnya.
Apakah frasa-sandi lebih lemah daripada string acak?
Tidak — kekuatannya bergantung hanya pada berapa banyak kata diambil dari daftar seberapa besar, dan keduanya ditampilkan. Enam kata dari daftar panjang EFF sekitar 77 bit, lebih dari sebuah sandi acak sepuluh-karakter. Yang melemahkan sebuah frasa-sandi adalah memilih katanya sendiri, yang ini tidak.
Apakah saya sebaiknya mengecualikan karakter mirip-rupa?
Jika seorang manusia akan membaca rahasia dari sebuah layar dan mengetiknya di tempat lain, ya: biayanya kecil dan sebuah token yang salah baca adalah sebuah tiket dukungan. Jika hanya perangkat lunak yang menanganinya, tak ada alasan untuk. Membuang 0, O, I, dan l mengambil alfabet dari 62 karakter ke 58, yang persis alfabet base58, dan menelan sekitar satu karakter panjang setiap dua belas.
Apakah mengapitalkan sebuah frasa-sandi membuatnya lebih kuat?
Tidak. Ia adalah perubahan yang sama diterapkan setiap kali, jadi ia tak menambah satu kemungkinan baru pun ke ruang frasa-sandi. Angka entropi di sini tetap ketika Anda menyalakannya, yang merupakan perilaku yang akurat. Opsi ada karena beberapa bidang sandi bersikeras pada sebuah huruf kapital.
Apakah ada yang saya hasilkan dikirim ke server?
Tidak. Pembangkitan berjalan sepenuhnya di browser Anda memakai pembangkit acak platform, tak ada yang diunggah atau dicatat, dan ia bekerja tanpa koneksi jaringan. Token tak disimpan di mana pun — memuat ulang halaman menghasilkan yang baru dan yang lama hilang.