Bahasa Melayu

Pengekodan, pelepasan aksara dan pencincangan

Base64 bukan penyulitan, btoa bukan UTF-8, encodeURI bukan encodeURIComponent dan SHA-256 bukan cincang kata laluan. Inilah yang sebenarnya dilakukan oleh setiap satu ini, dan kesilapan khusus yang berikut daripada menganggap sebaliknya.

Pengekodan bukan penyulitan, dan ia bukan pemampatan

Pengekodan mengubah cara data ditulis. Penyulitan mengubah siapa yang boleh membacanya. Mampatan mengubah jumlah ruang yang diperlukan. Ini adalah tiga pekerjaan yang berbeza, dan base64 sahaja melakukan yang pertama — teruk, jika anda mengharapkan salah satu daripada dua yang lain.

Base64 mengambil tiga bait pada satu masa dan menulisnya semula sebagai empat aksara yang diambil daripada abjad simbol 64. Empat aksara yang membawa tiga bait bermakna output sentiasa kira-kira 33% lebih besar daripada input, ditambah padding. Ia wujud kerana banyak infrastruktur — pengepala e-mel, pengepala HTTP, JSON nilai rentetan, URL, atribut XML — telah direka bentuk untuk teks dan mangle atau menolak bait sewenang-wenangnya. Base64 ialah penyesuai yang membolehkan anda menolak bait melalui paip berbentuk teks.

Sesiapa sahaja boleh membalikkannya serta-merta, tanpa kunci, kerana tiada kunci. Jika anda membuat asas64 kata laluan, anda telah menerbitkan kata laluan dalam format yang agak menyusahkan. Ini penting kerana output base64 kelihatan dikacau oleh mata manusia, iaitu harta yang membuatkan orang mempercayainya untuk perkara yang tidak dapat dilakukannya.

Mengapa btoa() pecah, dan dua cara berbeza ia pecah

Pelayar memberi anda btoa() dan atob(), dan ia lebih lama daripada API teks moden. btoa ditakrifkan melalui "rentetan binari": rentetan di mana setiap unit kod ialah bait tunggal, daripada 0 hingga 255. Teks bukan itu.

Kegagalan pertama adalah kuat. Panggil btoa("世界") dan anda mendapat InvalidCharacterError, kerana U+4E16 tidak muat dalam bait. Kegagalan yang kuat adalah jenis yang baik — anda melihatnya dengan segera dan pergi mencari pembetulan.

Kegagalan kedua adalah senyap, dan ia adalah yang mencapai pengeluaran. Watak ialah U+00E9, yang sesuai dalam bait. Jadi btoa("kafe") kembali dengan gembira, pengekodan é sebagai bait tunggal 0xE9. Tetapi é dalam UTF-8 ialah dua bait, 0xC3 0xA9. Base64 yang baru anda hasilkan menyahkod, dalam setiap sistem lain di bumi, kepada sesuatu yang bukan teks anda. Anda akan mengetahui beberapa minggu kemudian apabila nama dalam pangkalan data telah bertukar menjadi aksara gantian.

Penyelesaiannya adalah untuk berhenti menganggap teks sebagai bait dan menukarnya secara eksplisit. TextEncoder menghasilkan UTF-8 bait; mengekod mereka. TextDecoder menukarkan bait kembali kepada teks, dan membinanya dengan { fatal: true } menjadikannya membuang pada urutan tidak sah dan bukannya menggantikan U+FFFD secara senyap-senyap, jadi penyahkod yang tidak mungkin betul gagal daripada mengembalikan omong kosong yang kelihatan munasabah. Itulah saluran paip yang digunakan oleh kit alat ini, itulah sebabnya emoji, menggabungkan tanda dan skrip kanan ke kiri semuanya pergi balik dengan tepat.

  1. Tukar teks kepada bait dengan TextEncoder — jangan sekali-kali indeks ke dalam rentetan.
  2. Kodkan bait ke base64.
  3. Untuk membalikkan: menyahkod base64 kepada bait, kemudian menyahkod bait sebagai UTF-8 dengan fatal: true.
  4. Jika langkah UTF-8 gagal, muatan adalah binari, bukan teks. Tunjukkannya sebagai hex dan bukannya berpura-pura.

base64 berbanding base64url, dan soalan padding

Standard base64 menggunakan + dan / sebagai dua simbol terakhirnya. Kedua-duanya bermakna dalam URL: + boleh dibaca sebagai ruang yang dikodkan dalam rentetan pertanyaan dan / ialah pemisah laluan. Jadi RFC 4648 mentakrifkan abjad kedua, base64url, yang menggantikan - dan _ sebaliknya. JWT menggunakannya, seperti kebanyakan format token dan banyak API.

Padding adalah pembolehubah lain. Pad base64 standard dengan = jadi panjang output sentiasa gandaan empat. base64url biasanya menggugurkan padding, kerana = sendiri merupakan watak janggal dalam URL dan panjangnya boleh dipulihkan secara aritmetik. Penyahkod yang berkeras pada pelapik akan menolak segmen JWT yang sah dengan sempurna.

Nasihat praktikal: penyahkod anda harus menerima kedua-dua abjad dan bertolak ansur dengan padding yang hilang, kerana anda jarang mengawal apa yang diserahkan kepada anda. Pengekod anda harus jelas tentang yang dipancarkan, kerana penerima mungkin mengambil berat. Utiliti base64 di sini melakukan perkara itu - ia menerima apa-apa yang munasabah dan membolehkan anda memilih dengan tepat apa yang dihasilkannya.

encodeURI dan encodeURIComponent: perbezaan dalam satu ayat

Kedua-dua peratus mengekod menggunakan UTF-8. Mereka sahaja berbeza dalam aksara yang mereka biarkan sahaja, dan perbezaan itu ialah keseluruhan cerita: encodeURIComponent pelepasan aksara dari pembatas yang dikhaskan, encodeURI tidak.

Pembatas terpelihara ialah aksara yang memberikan URL strukturnya: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. encodeURI menganggap anda menyerahkannya URL yang sudah berstruktur dengan betul dan mesti kekal seperti itu, jadi ia mengekalkannya — ia tidak akan menukar https:// menjadi https%3A%2F%2F. encodeURIComponent menganggap anda menyerahkannya satu bahagian yang akan dijatuhkan ke dalam slot, jadi ia pelepasan aksara daripadanya, memastikan bahagian itu tidak boleh keluar dari slotnya.

Pepijat yang dihasilkan ini adalah mekanikal sepenuhnya. Ambil nilai carian a&b=c. Kodkannya dengan encodeURI dan tambahkannya sebagai ?q=a&b=c, dan anda telah mencipta dua parameter secara senyap: q kini sahaja "a", dan b=c yang sesat telah muncul. Kodkannya dengan encodeURIComponent dan anda mendapat ?q=a%26b%3Dc, satu parameter, nilai yang betul. Kelas pepijat yang sama membolehkan nilai yang dibuat menyuntik parameter ke dalam URL binaan kod anda — itulah sebabnya "menggunakan borang komponen untuk nilai" ialah peraturan keselamatan, bukan sahaja ketepatan.

Pengekodan borang ialah peraturan ketiga yang kelihatan seperti yang kedua. application/x-www-form-urlencoded menulis ruang sebagai + bukannya %20. Jika anda menyahkod badan borang dengan decodeURIComponent biasa, setiap tanda tambah dalam data menjadi ruang. Setiap kotak carian yang pernah mengubah "C++" menjadi "C" ialah pepijat ini.

HTML entiti dan mengapa menyahkodnya dengan innerHTML ialah tabiat buruk

Melarikan diri untuk HTML adalah sempit dan difahami dengan baik: & menjadi &amp;, < menjadi &lt;, > menjadi &gt;, dan nilai atribut dalam " dan ' perlu melarikan diri juga. Lima aksara. Melarikan diri kepada setiap hari yang dinamakan — menukarkan untuk setiap hari yang dinamakan — bertukar untuk setiap hari yang dinamakan — bertukar untuk setiap hari yang diberi nama pengekodan aksara yang tidak pasti, dan kini penggayaan pilihan dan bukannya keselamatan.

Penyahkodan ialah tempat tabiat buruk itu hidup. Helah satu baris yang muncul dalam setiap jawapan adalah untuk menetapkan rentetan kepada innerHTML elemen yang terpisah dan membaca kembali TextContentnya. Ia berfungsi, dan ia adalah idea yang tidak baik. Anda telah menyerahkan input yang tidak dipercayai kepada penghurai HTML, yang membina nod DOM sebenar daripadanya. <img src=x onerror=...> dalam rentetan itu menjadi elemen imej sebenar dengan pengendali ralat sebenar dilampirkan; jika subpokok itu pernah dimasukkan ke dalam dokumen, ia akan berjalan. Ia juga secara senyap memusnahkan data anda: teg dalam input lenyap dan bukannya pergi balik, kerana penghurai mentafsirkannya sebagai markup dan bukannya teks.

Penyahkodan entiti dengan betul tidak memerlukan penghurai sama sekali: padankan rujukan, cari nama dalam jadual atau buat aritmetik untuk rujukan berangka. Itu adalah beberapa dozen baris, ia tidak boleh melaksanakan apa-apa, dan ia pergi balik dengan setia. Kit alat ini melakukannya dengan cara itu, itulah sebabnya menampal teg skrip ke dalam penyahkod entiti menunjukkan kepada anda teg skrip.

Memilih cincang, dan tiga soalan yang menentukannya

Cincang kriptografi menukar mana-mana input kepada ringkasan panjang tetap, supaya mencari dua input dengan ringkasan yang sama tidak boleh dilaksanakan. Sifat itulah yang membolehkan ringkasan berdiri untuk data — dalam tandatangan, semakan integriti atau alamat kandungan.

Soalan pertama: adakah anda melindungi daripada kemalangan atau menentang musuh? Checksum yang melindungi daripada muat turun yang rosak sahaja perlu menangkap lambungan rawak; CRC32 tidak mengapa. Cernaan yang boleh dimanfaatkan oleh penyerang daripada perlanggaran memerlukan cincangan yang masih berdiri. Perbezaan itulah sebabnya SHA-1 bukan sekadar "lama".

SHA-1 rosak, konkrit. Dalam 2017 kerja SHAttered menghasilkan dua fail PDF berbeza dengan SHA-1 digest yang sama. Dalam 2020, "SHA-1 ialah a Shambles" menunjukkan perlanggaran awalan yang dipilih — varian yang lebih kuat dan jauh lebih berbahaya, kerana ia membenarkan penyerang melanggar dua dokumen yang berbeza bermakna berbanding dua gumpalan yang dibina dengan teliti. Jika keselamatan sistem bergantung pada rintangan perlanggaran SHA-1, keselamatan itu hilang. SHA-1 kekal dalam kit alat ini kerana id objek git dan ekor panjang tandatangan API masih menggunakannya dan anda perlu dapat menghasilkan semula nilai tersebut. Menghasilkan semula nilai tidak sama dengan bergantung padanya.

Soalan kedua: adakah input kata laluan? Jika ya, tiada satu pun daripada ini adalah jawapannya. SHA-256 direka untuk menjadi pantas dan pantas adalah salah untuk kata laluan: ini bermakna penyerang dengan pangkalan data anda boleh mencuba berbilion-bilion tekaan sesaat. Kata laluan memerlukan fungsi yang sengaja perlahan, keras memori dengan garam setiap pengguna — Argon2id, scrypt atau bcrypt. Ini bukan satu nuansa; menggunakan SHA-256 untuk kata laluan ialah satu-satunya kesilapan pencincangan serius yang paling biasa.

Soalan ketiga: adakah anda memerlukan keyed digest? Jika anda mengesahkan mesej dan bukannya mengecap jari, anda mahu HMAC, bukan cincang kosong. Menggabungkan rahsia dan mencincangnya adalah matlamat sendiri klasik terhadap serangan lanjutan panjang; HMAC wujud kerana pembinaan itu lebih sukar untuk diperbaiki daripada yang kelihatan.

Untuk segala-galanya — cap jari fail, alamat kandungan, atribut integriti — SHA-256 ialah lalai yang wajar dan SHA-512 selalunya lebih pantas pada perkakasan 64-bit sambil memberikan cernaan yang lebih luas.

Mengapa cincang di sini datang daripada pelayar

Rumusan dalam kit alat ini dikira oleh SubtleCrypto, pelaksanaan Web Crypto sendiri oleh pelayar, bukan oleh JavaScript yang dihantar dari tapak ini. Itu adalah pilihan yang disengajakan: pelaksanaan pelayar diaudit, diselenggara dan biasanya dijalankan sebagai kod asli yang dioptimumkan. SHA-256 tulisan tangan dalam himpunan halaman adalah lebih banyak kod untuk dipercayai tanpa faedah.

Ia mempunyai satu akibat yang boleh dilihat. Web Crypto sahaja didedahkan dalam konteks selamat, yang bermaksud https:// atau localhost. Buka halaman ini di atas HTTP biasa pada alamat LAN dan crypto.subtle akan tidak ditentukan, jadi utiliti cincang akan memberitahu anda dengan begitu jelas dan bukannya gagal secara senyap atau menggantikan sesuatu yang lebih lemah.

Alasan yang sama memacu penjana UUID. crypto.randomUUID() juga selamat-konteks sahaja, jadi jika ia tidak tersedia, kit alat akan kembali kepada crypto.getRandomValues() — yang masih merupakan sumber selamat dari segi kriptografi yang sama — dan menetapkan versi serta bit varian itu sendiri. Perkara yang tidak akan dilakukan ialah kembali kepada Math.random(). Itu ialah PRNG bukan kriptografi pantas yang keadaan dalamannya boleh dipulihkan daripada jangka pendek outputnya, dan pengecam mempunyai tabiat malang untuk dinaikkan pangkat menjadi kunci sesi dan pautan set semula kata laluan. Jika tiada sumber selamat wujud, alat ini tidak menghasilkan apa-apa dan menyatakan sebabnya.

Apa yang berlaku kepada apa yang anda tampal

  • Setiap penukaran, cincang, penyahkod dan perbezaan berjalan dalam tab pelayar anda. Tiada input dimuat naik, dilog atau disimpan pada pelayan, kerana tiada pelayan yang terlibat selepas halaman dimuatkan.
  • Hashes datang daripada pelaksanaan Web Crypto sendiri pelayar, dan UUID daripada penjana rawak yang selamat secara kriptografi. Kedua-duanya tidak melibatkan panggilan rangkaian.
  • Tiada apa-apa yang anda taip ditulis pada storan tempatan atau kuki. Memuat semula halaman akan membuangnya; menutup tab membuangnya.
  • Analitis seluruh tapak berjalan sahaja pada hos pengeluaran kanonik yang dikonfigurasikan dan didedahkan dalam Dasar Privasi; tempatan dan hos pratonton menolaknya. Nilai, token, URL dan kandungan fail yang ditampal dikecualikan daripada acara analitis ToolAcre sendiri. Pengiklanan dilumpuhkan dalam konfigurasi semasa.
  • Yang berkata: kunci JWT atau API ialah bukti kelayakan langsung. Tabiat selamat adalah jangan sekali-kali menampal satu ke halaman web yang anda tidak tulis, walau bagaimanapun boleh dipercayai dakwaannya — termasuk yang ini.

Soalan

Adakah base64 cara untuk menyembunyikan data?

Tidak. Ia adalah perwakilan teks boleh balik tanpa kunci, boleh dinyahkod oleh sesiapa sahaja dalam sepersekian saat. Ia menjadikan data bertahan dalam saluran teks sahaja; ia tidak menjadikan ia rahsia. Apa-apa sahaja yang benar-benar sensitif memerlukan penyulitan, dan hasil yang disulitkan sering kemudiannya dikodkan base64 untuk pengangkutan — yang merupakan punca kekeliruan.

Mengapa base64 saya lebih panjang daripada input?

Oleh kerana empat aksara output membawa tiga bait input, jadi output adalah kira-kira 4/3 saiz, ditambah sehingga dua aksara padding. Itu adalah wujud dalam format. Jika saiz penting, mampatkan sebelum pengekodan — jangan sekali-kali selepas itu, kerana output base64 memampat dengan buruk.

Fungsi pengekodan URL yang manakah harus saya gunakan?

Gunakan encodeURIComponent untuk mana-mana bahagian tunggal yang anda masukkan ke dalam URL: nilai pertanyaan, segmen laluan, serpihan. Gunakan encodeURI sahaja apabila anda mempunyai keseluruhan URL yang telah berstruktur yang sahaja mengandungi ruang atau bukan-ASCII. Jika anda sedang membina rentetan pertanyaan, pilih URLSearchParams, yang menggunakan peraturan yang betul untuk anda dan mengendalikan perbezaan space-as-plus.

Mengapakah penyahkod saya membuang "URI cacat"?

Kerana % dalam input tidak diikuti oleh dua digit heksadesimal. Biasanya teks mengandungi tanda peratus literal — "50% off" — yang tidak pernah dikodkan. Peratusan literal mesti ditulis sebagai %25. Utiliti URL di sini melaporkan kedudukan sebenar pelarian yang menyinggung dan bukannya sahaja menolak.

Bolehkah saya menggunakan SHA-256 untuk menyimpan kata laluan?

Tidak. SHA-256 adalah pantas mengikut reka bentuk, yang bermaksud penyerang yang mencuri pangkalan data anda boleh menguji berbilion kata laluan calon sesaat pada perkakasan komoditi. Kata laluan memerlukan fungsi yang perlahan, keras memori, masin: Argon2id, scrypt atau bcrypt. Ini adalah kesilapan serius yang paling biasa di kawasan ini.

Mengapakah SHA-1 masih di sini jika ia rosak?

Kerana anda masih perlu menghasilkan semula nilai SHA-1 yang sudah wujud: id objek git, cap jari sijil TLS lama, tandatangan permintaan API lama. Keupayaan mengira nilai untuk saling kendali adalah berbeza daripada bergantung pada nilai untuk keselamatan. Setiap tempat SHA-1 muncul dalam kit alat ini dilabelkan sewajarnya.

Mengapakah dua alat memberikan cincangan yang berbeza untuk teks yang sama?

Hampir selalu perbezaan dalam bait, bukan algoritma. Penyebab biasa ialah baris baharu yang mengekori (fail berakhir dengan satu; kotak teks mungkin tidak), pengekodan teks yang berbeza, atau CRLF berbanding penghujung baris LF. Alat ini mencincang UTF-8 bait dengan tepat apa yang anda taip dan menunjukkan kepada anda kiraan bait, yang biasanya menjadikan percanggahan itu jelas.

Had

  • Jadual entiti HTML yang dinamakan meliputi subset praktikal — aksara kritikal penanda, tipografi, mata wang, anak panah, matematik, Greek dan Latin-1 — bukan semua rujukan bernama 2,231 HTML5. Nama yang tidak dikenali dilaporkan dan dibiarkan tepat seperti yang ditulis dan bukannya diduga.
  • Penyahkodan entiti memerlukan koma bertitik penamat. HTML5 bertolak ansur dengan segelintir rujukan warisan tanpa satu, tetapi menyahkodnya dengan betul bergantung pada konteks penanda sekeliling, yang tidak ada pada alat teks kendiri.
  • Hashing dan generasi UUID memerlukan konteks selamat (https:// atau localhost) kerana Web Crypto tidak terdedah sebaliknya. Alat ini melaporkan perkara ini dan bukannya menggantikan pelaksanaan yang lebih lemah.
  • Sahaja SHA-1, SHA-256, SHA-384 dan SHA-512 tersedia, kerana itulah yang SubtleCrypto laksanakan. MD5 tidak hadir kerana pilihan dan juga keperluan.
  • Tiada HMAC, tiada terbitan kunci dan tiada penyulitan di sini. Mereka memerlukan pengurusan utama, yang bukan sesuatu halaman yang anda temui di internet harus dikendalikan.
  • Semuanya dihadkan oleh memori peranti anda, kerana semuanya berjalan dalam satu tab pelayar. Input dihadkan — beberapa megabait setiap utiliti — dan alat itu menolak kerja yang terlalu besar dan bukannya membeku.