Piszę login do forum i muszę zaszyfrować hasło po stronie klienta w javascript przed wysłaniem go na serwer. Mam problem ze znalezieniem implementacji SHA-256, której mogę zaufać. Spodziewałem się, że będzie jakiś autorytatywny skrypt, z którego wszyscy korzystali, ale znajduję mnóstwo różnych projektów, z których każdy ma własne implementacje.
Zdaję sobie sprawę, że używanie kryptowalut innych ludzi jest zawsze przejawem wiary, chyba że masz kwalifikacje do samodzielnego przejrzenia i że nie ma uniwersalnej definicji „godnego zaufania”, ale wydaje się to czymś powszechnym i na tyle ważnym, że powinno istnieć konsensusu co do tego, czego użyć. Czy jestem po prostu naiwny?
Edytuj, ponieważ pojawia się dużo w komentarzach: Tak, ponownie wykonujemy bardziej rygorystyczny hash po stronie serwera. Haszowanie po stronie klienta nie jest ostatecznym wynikiem, który zapisujemy w bazie danych. Haszowanie po stronie klienta jest spowodowane żądaniem klienta. Nie podali konkretnego powodu, prawdopodobnie po prostu lubią przesadę.
źródło
Odpowiedzi:
PRZESTARZAŁE: Wiele nowoczesnych przeglądarek ma teraz pierwszorzędną obsługę operacji kryptograficznych. Zobacz odpowiedź Witalija Zdanewicza poniżej.
Biblioteka Stanford JS Crypto zawiera implementację SHA-256. Chociaż kryptowaluty w JS nie są tak dobrze sprawdzone, jak inne platformy wdrożeniowe, ta jest przynajmniej częściowo opracowana i do pewnego stopnia sponsorowana przez Dana Boneha , który jest dobrze znaną i zaufaną marką w kryptografii , i oznacza, że projekt jest nadzorowany przez kogoś, kto faktycznie wie, co robi. Projekt jest również wspierany przez NSF .
Warto jednak zauważyć ...
... że jeśli przed przesłaniem haszujesz hasło po stronie klienta, to hash jest hasłem , a oryginalne hasło staje się nieistotne. Osoba atakująca musi tylko przechwycić hash, aby podszyć się pod użytkownika, a jeśli ten skrót jest przechowywany na serwerze w postaci niezmienionej, serwer przechowuje prawdziwe hasło (skrót) w postaci zwykłego tekstu .
Twoje bezpieczeństwo jest teraz gorsze, ponieważ zdecydowałeś dodać własne ulepszenia do tego, co wcześniej było zaufanym schematem.
źródło
Na https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest znalazłem ten fragment wykorzystujący wewnętrzny moduł js:
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; }
Zauważ, że
crypto.subtle
dostępne tylko whttps
lublocalhost
- na przykład dla lokalnego rozwoju zpython3 -m http.server
musisz dodać tę linię do/etc/hosts
:0.0.0.0 localhost
Uruchom ponownie - i możesz otworzyć
localhost:8000
podczas pracycrypto.subtle
.źródło
Implementacja SHA-256 w Forge jest szybka i niezawodna.
Aby uruchomić testy na kilku implementacjach JavaScript SHA-256, przejdź do http://brillout.github.io/test-javascript-hash-implementations/ .
Wyniki na moim komputerze sugerują, że forge jest najszybszą implementacją, a także znacznie szybszą niż biblioteka Stanford Javascript Crypto Library (sjcl) wymieniona w zaakceptowanej odpowiedzi.
Forge ma rozmiar 256 KB, ale wyodrębnienie kodu związanego z SHA-256 zmniejsza rozmiar do 4,5 KB, zobacz https://github.com/brillout/forge-sha256
źródło
npm install node-forge
, ale teraz, jak użyć biblioteki, aby utworzyć hash z ciągufoo
?Dla zainteresowanych jest to kod do tworzenia skrótu SHA-256 przy użyciu
sjcl
:import sjcl from 'sjcl' const myString = 'Hello' const myBitArray = sjcl.hash.sha256.hash(myString) const myHash = sjcl.codec.hex.fromBits(myBitArray)
źródło
Nie, nie ma sposobu, aby poprawić bezpieczeństwo hasła za pomocą JavaScript przeglądarki. Gorąco polecam przeczytanie tego artykułu . W twoim przypadku największym problemem jest problem jaja kurzego:
[…]
Co prowadzi do tego:
Zasadniczo problem jest następujący:
Lub alternatywnie
Uwaga: SHA-256 nie jest do tego odpowiedni, ponieważ tak łatwo jest brutalnie wymusić niesolone, nie iteracyjne hasła . Jeśli zdecydujesz się to zrobić tak, poszukaj realizacji bcrypt , scrypt lub PBKDF2 .
źródło
Uważam, że ta implementacja jest bardzo łatwa w użyciu. Posiada również hojną licencję w stylu BSD:
jsSHA: https://github.com/Caligatio/jsSHA
Potrzebowałem szybkiego sposobu na uzyskanie reprezentacji ciągu szesnastkowego skrótu SHA-256. Zajęło tylko 3 linie:
var sha256 = new jsSHA('SHA-256', 'TEXT'); sha256.update(some_string_variable_to_hash); var hash = sha256.getHash("HEX");
źródło
Oprócz biblioteki Stanforda, o której wspomniał Tylerl. Uważam, że jsrsasign jest bardzo przydatny (repozytorium Github tutaj: https://github.com/kjur/jsrsasign ). Nie wiem, na ile jest to godne zaufania, ale użyłem jego API SHA256, Base64, RSA, x509 itp. I działa całkiem nieźle. W rzeczywistości obejmuje również bibliotekę Stanford.
Jeśli wszystko, co chcesz zrobić, to SHA256, jsrsasign może być przesadą . Ale jeśli masz inne potrzeby w pokrewnym obszarze, uważam, że to dobrze pasuje.
źródło