Saya menulis login untuk forum, dan perlu hash sisi klien kata sandi di javascript sebelum mengirimkannya ke server. Saya mengalami masalah dalam mencari tahu implementasi SHA-256 mana yang benar-benar dapat saya percayai. Saya berharap akan ada semacam skrip otoritatif yang digunakan semua orang, tetapi saya menemukan banyak proyek berbeda semua dengan penerapannya sendiri.
Saya menyadari bahwa menggunakan crypto orang lain selalu merupakan lompatan keyakinan kecuali Anda memenuhi syarat untuk meninjaunya sendiri, dan bahwa tidak ada definisi universal tentang "dapat dipercaya", tetapi ini sepertinya sesuatu yang umum dan cukup penting sehingga harus ada semacam konsensus tentang apa yang akan digunakan. Apakah saya hanya naif?
Edit karena muncul banyak di komentar: Ya, kami melakukan hash yang lebih ketat lagi di sisi server. Hash sisi klien bukanlah hasil akhir yang kita simpan di database. Hash sisi klien adalah karena klien manusia memintanya. Mereka belum memberikan alasan khusus mengapa, mungkin mereka suka berlebihan.
sumber
Jawaban:
OUTDATED: Banyak browser modern sekarang memiliki dukungan kelas satu untuk operasi crypto. Lihat jawaban Vitaly Zdanevich di bawah ini.
The Stanford JS Crypto Library berisi implementasi SHA-256. Sementara crypto di JS tidak benar-benar merupakan upaya yang diperiksa dengan baik seperti platform implementasi lainnya, yang satu ini setidaknya sebagian dikembangkan oleh, dan sampai batas tertentu disponsori oleh, Dan Boneh , yang merupakan nama mapan dan tepercaya dalam kriptografi , dan berarti bahwa proyek tersebut memiliki pengawasan oleh seseorang yang benar-benar tahu apa yang dia lakukan. Proyek ini juga didukung oleh NSF .
Namun, perlu diperhatikan
bahwa ... ... bahwa jika Anda melakukan hash pada sisi klien kata sandi sebelum mengirimkannya, maka hash adalah kata sandinya , dan kata sandi asli menjadi tidak relevan. Penyerang hanya perlu mencegat hash untuk menyamar sebagai pengguna, dan jika hash itu disimpan tanpa modifikasi di server, maka server menyimpan kata sandi yang sebenarnya (hash) dalam teks biasa .
Jadi keamanan Anda sekarang lebih buruk karena Anda memutuskan untuk menambahkan perbaikan Anda sendiri ke skema yang sebelumnya dipercaya.
sumber
Di https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest saya menemukan cuplikan ini yang menggunakan modul js internal:
async function sha256(message) { // encode as UTF-8 const msgBuffer = new TextEncoder().encode(message); // hash the message const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); // convert ArrayBuffer to Array const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert bytes to hex string const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join(''); return hashHex; }
Perhatikan bahwa
crypto.subtle
hanya tersedia padahttps
ataulocalhost
- misalnya untuk pengembangan lokalpython3 -m http.server
Anda dengan Anda perlu menambahkan baris ini ke/etc/hosts
:0.0.0.0 localhost
Reboot - dan Anda dapat membuka
localhost:8000
dengan bekerjacrypto.subtle
.sumber
Implementasi SHA-256 Forge cepat dan andal.
Untuk menjalankan pengujian pada beberapa implementasi JavaScript SHA-256, buka http://brillout.github.io/test-javascript-hash-implementations/ .
Hasil pada mesin saya menyarankan forge untuk menjadi implementasi tercepat dan juga jauh lebih cepat daripada Perpustakaan Crypto Javascript Stanford (sjcl) yang disebutkan dalam jawaban yang diterima.
Forge berukuran 256 KB, tetapi mengekstrak kode terkait SHA-256 mengurangi ukurannya menjadi 4,5 KB, lihat https://github.com/brillout/forge-sha256
sumber
npm install node-forge
, tetapi sekarang, bagaimana cara menggunakan perpustakaan membuat hash dari stringfoo
?Bagi yang tertarik, berikut kode untuk membuat hash SHA-256 menggunakan
sjcl
:import sjcl from 'sjcl' const myString = 'Hello' const myBitArray = sjcl.hash.sha256.hash(myString) const myHash = sjcl.codec.hex.fromBits(myBitArray)
sumber
Tidak, tidak ada cara menggunakan JavaScript browser untuk meningkatkan keamanan kata sandi. Saya sangat menyarankan Anda membaca artikel ini . Dalam kasus Anda, masalah terbesar adalah masalah telur ayam:
[...]
Yang mengarah ke ini:
Pada dasarnya masalahnya adalah ini:
Atau sebagai alternatif,
Catatan: Selain itu, SHA-256 tidak cocok untuk ini, karena sangat mudah untuk memaksa kata sandi non-iterasi tanpa salt . Jika Anda tetap memutuskan untuk melakukannya, cari implementasi dari bcrypt , scrypt atau PBKDF2 .
sumber
Saya menemukan implementasi ini sangat mudah digunakan. Juga memiliki lisensi gaya BSD yang murah hati:
jsSHA: https://github.com/Caligatio/jsSHA
Saya membutuhkan cara cepat untuk mendapatkan representasi hex-string dari hash SHA-256. Hanya butuh 3 baris:
var sha256 = new jsSHA('SHA-256', 'TEXT'); sha256.update(some_string_variable_to_hash); var hash = sha256.getHash("HEX");
sumber
Selain lib Stanford yang disebutkan Tylerl. Saya menemukan jsrsasign sangat berguna (repo Github di sini: https://github.com/kjur/jsrsasign ). Saya tidak tahu bagaimana tepatnya dapat dipercaya, tetapi saya telah menggunakan API-nya SHA256, Base64, RSA, x509 dll dan bekerja dengan cukup baik. Bahkan, itu termasuk lib Stanford juga.
Jika semua yang Anda ingin lakukan adalah SHA256, jsrsasign mungkin berlebihan. Tetapi jika Anda memiliki kebutuhan lain di bidang terkait, saya rasa itu cocok.
sumber