Czy istnieją jakieś implementacje javascript SHA-256, które są ogólnie uważane za godne zaufania?

Piszę login do forum i muszę hashować hasło po stronie klienta w javascript przed wysłaniem go na serwer. Mam problem z ustaleniem, której implementacji SHA-256 mogę zaufać. Spodziewałem się, że będzie jakiś autorytatywny skrypt, którego wszyscy używali, ale znajduję mnóstwo różnych projektów, wszystkie z własnymi implementacjami.

Zdaję sobie sprawę, że używanie cudzych krypto jest zawsze skokiem wiary, chyba że masz kwalifikacje, aby je przejrzeć siebie, i że nie ma uniwersalnej definicji "godny zaufania" , ale wydaje się to czymś powszechnym i na tyle ważnym, że powinno być jakiś konsensus co do tego, czego używać. Jestem naiwna?

Edit ponieważ pojawia się dużo w komentarzach: tak, robimy bardziej rygorystyczny hash po stronie serwera. Haszowanie po stronie klienta nie jest końcowym wynikiem, który zapisujemy w bazie danych. Haszowanie po stronie klienta polega na tym, że klient ludzki tego żąda. Nie podali konkretnego pewnie lubią przesadę.

Author: jono, 2013-08-19

7 answers

Biblioteka Stanford js Crypto Library zawiera implementację SHA-256. Chociaż krypto w JS nie jest tak dobrze sprawdzonym przedsięwzięciem, jak inne platformy implementacyjne, ta jest przynajmniej częściowo opracowana i w pewnym stopniu sponsorowana przez dana Boneha, który jest ugruntowaną i zaufaną nazwą w kryptografii i oznacza, że projekt ma pewien nadzór przez kogoś, kto faktycznie wie, co robi. Projekt jest również wspierany przez NSF .

warto jednak zwrócić uwagę...
... jeśli hashujesz hasło po stronie klienta przed jego wysłaniem, wtedy jest hasłem , A oryginalne hasło staje się nieistotne. Atakujący musi tylko przechwycić hash, aby podszywać się pod użytkownika, a jeśli ten hash jest przechowywany niezmodyfikowany na serwerze, , to serwer przechowuje true hasło (hash) w zwykłym tekście .

Więc Twoje bezpieczeństwo jest teraz gorzej ponieważ zdecydowałeś dodać własne ulepszenia do tego, co wcześniej było zaufanym schematem.

 62
Author: tylerl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 13:14:46

Implementacja SHA-256 firmy 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 mojej maszynie sugerują, że forge jest najszybszą implementacją, a także znacznie szybszą niż Stanford Javascript Crypto Library (Sjcl) wspomniana w zaakceptowanej odpowiedzi.

Forge ma wielkość 256 KB, ale wydobywanie kodu związanego z SHA-256 zmniejsza rozmiar do 4,5 KB, zobacz https://github.com/brillout/forge-sha256

 11
Author: brillout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-22 19:13:12

Nie, Nie ma sposobu na użycie JavaScript przeglądarki w celu poprawy bezpieczeństwa hasła. Gorąco polecam przeczytać Ten artykuł . W Twoim przypadku największym problemem jest problem z jajkiem:

Jaki jest problem z dostarczaniem kryptografii Javascript?

Jeśli nie ufasz sieci, która dostarczy hasło lub, co gorsza, nie ufasz serwerowi, który nie zachowa tajemnic użytkownika, nie możesz ufać, że dostarczy kod bezpieczeństwa. Ten sam napastnik, który był wąchanie haseł lub czytanie pamiętników przed wprowadzeniem krypto to po prostu przejmowanie kodu kryptograficznego po tym, jak to zrobisz.

[...]

Dlaczego nie mogę użyć TLS/SSL do dostarczenia kodu kryptograficznego Javascript?

Możesz. Jest to trudniejsze niż się wydaje, ale bezpiecznie przesyłasz Javascript crypto do przeglądarki za pomocą SSL. Problem polega na tym, że po ustanowieniu bezpiecznego kanału z SSL, nie potrzebujesz już kryptografii Javascript; masz" prawdziwą " kryptografię.

Które prowadzi do tego:

Problem z uruchomieniem kodu kryptograficznego w Javascript polega na tym, że praktycznie każda funkcja, od której zależy krypto, może zostać po cichu nadpisana przez dowolny fragment treści używany do budowy strony hostingowej. Bezpieczeństwo kryptograficzne może zostać cofnięte na początku procesu (poprzez generowanie fałszywych liczb losowych lub manipulowanie stałymi i parametrami używanymi przez algorytmy) lub później (poprzez wysyłanie kluczowego materiału z powrotem do atakującego) lub - - - {22]}w najbardziej prawdopodobnym scenariuszu --- przez całkowicie pomijając krypto.

Nie ma wiarygodnego sposobu, aby jakikolwiek fragment kodu Javascript zweryfikował jego środowisko wykonawcze. Javascript Crypto code nie może zapytać :" czy naprawdę mam do czynienia z generatorem liczb losowych, czy z jakimś faksymile jednego dostarczonego przez atakującego?" i z pewnością nie można stwierdzić "nikt nie może nic zrobić z tą tajemnicą kryptograficzną, z wyjątkiem sposobów, które ja, autor, aprobuję". są to dwie właściwości, które często są dostarczane w innych środowiska, które używają crypto, a są one niemożliwe w Javascript.

W zasadzie problem jest taki:

  • Twoi klienci nie ufają Twoim serwerom, więc chcą dodać dodatkowy kod bezpieczeństwa.
  • ten kod bezpieczeństwa jest dostarczany przez twoje serwery (te, którym nie ufają).

Lub alternatywnie

  • Twoi klienci nie ufają SSL, więc chcą, żebyś używał dodatkowego kodu bezpieczeństwa.
  • ten kod bezpieczeństwa jest dostarczany poprzez SSL.

Uwaga: również SHA-256 Nie nadaje się do tego, ponieważ tak łatwo jest brute force unsalted non-iterated passwords. Jeśli i tak zdecydujesz się to zrobić, poszukaj implementacji bcrypt, scrypt lub PBKDF2 .

 8
Author: Brendan Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-04 16:29:28

Uznałem tę implementację za bardzo łatwą w użyciu. Posiada również hojną licencję w stylu BSD:

JsSHA: https://github.com/Caligatio/jsSHA

Potrzebowałem szybkiego sposobu, aby uzyskać hex-string reprezentacji SHA-256 hash. Zajęło to tylko 3 linijki:

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");
 7
Author: cobbzilla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-02 00:28:05

On https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest znalazłem ten fragment, który używa wewnętrznego modułu js:

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder('utf-8').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;
}
 6
Author: Vitaly Zdanevich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 05:05:15

Dla zainteresowanych jest to kod do tworzenia hasha SHA-256 za pomocą sjcl:

import sjcl from 'sjcl'

const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)
 3
Author: Danny Sullivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 01:37:39

Poza lib Stanforda, o którym wspomniał tylerl. Znalazłem jsrsasign bardzo przydatne (Github repo tutaj: https://github.com/kjur/jsrsasign ). Nie wiem, jak to jest godne zaufania, ale korzystałem z jego API SHA256, Base64, RSA, x509 itp. i działa całkiem nieźle. W rzeczywistości obejmuje również Stanford lib.

Jeśli wszystko co chcesz zrobić to SHA256, jsrsasign może być przesadą. Ale jeśli masz inne potrzeby w pokrewnej dziedzinie, czuję, że to dobrze pasuje.

 1
Author: Faraway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 22:29:03