Skąd powinny pochodzić wartości skrótu soli?

12

Kiedy dodajesz wartości soli do wartości skrótu dla czegoś takiego jak hasło, którego nie można zapisać zwykłym tekstem, jakie jest najlepsze miejsce, aby uzyskać wartości soli? Dla kontekstu załóżmy, że dotyczy to haseł do logowania na stronie internetowej.

Morgan Herlocker
źródło
@DevArt, pomyślałem, że lepiej tu pasuje, ponieważ wymaga bardzo subiektywnej odpowiedzi. Wartość soli można pobrać z dowolnego miejsca, więc pytam: „Jak myślisz, gdzie jest najbezpieczniejsza lokalizacja do pobierania wartości soli z: klienta lub serwera?”
Morgan Herlocker

Odpowiedzi:

7

Zwykle mam kolumnę created TIMESTAMPw tabeli użytkowników, dzięki czemu mogę zobaczyć, kiedy użytkownik się zarejestrował. Nie lubię dodawać dodatkowej kolumny dla Soli, więc używam kolumny znacznika czasu jako soli:

SHA1(password + created)
Jonas
źródło
Zakładam, że kiedy użytkownik zaloguje się ponownie, wyciągniesz datę na podstawie nazwy użytkownika, kiedy ponownie spróbujesz zweryfikować?
Morgan Herlocker
1
@Prof: Tak, tak samo jak w przypadku konkretnej kolumny dla soli, więc nie ma różnicy w tej perspektywie.
Jonas
7

Czy to ma znaczenie?

Sól służy dwóm celom. Uniemożliwia to stosowanie dużych tabel wstępnie ustawionych haseł („tęczowych tabel”) i sprawia, że ​​identyczne hasła wyglądają inaczej na liście skrótów. Zróżnicowanie identycznych haseł pomaga uniknąć problemu polegającego na tym, że kilka osób używa jednego konkretnego hasła, które prawdopodobnie jest często słabym hasłem.

Dlatego każde konto powinno mieć własną unikalną sól, a sole nie powinny być zbyt przewidywalne, w tym sensie, że nie będzie grupy soli, która prawdopodobnie wystąpi. (Jeśli wiele witryn zaczynało się od 1 i policzyło, złoczyńcy mogliby budować tęczowe tabele, w tym na przykład sole o niskiej liczbie.) Nie muszą być losowe w żadnym innym sensie niż ogólnie nieprzewidywalne. Nie są one bardziej tajne niż sam hash, więc nie muszą być szczególnie niewygodne.

Użyj dowolnej dogodnej metody, aby wygenerować sól. Jeśli istnieje wiele potencjalnych wartości soli (wczesne systemy uniksowe często używały dwóch bajtów, dla możliwej liczby 65536) w porównaniu do liczby kont, pół losowe przypisanie prawie nigdy nie dałoby duplikatu soli.

David Thornley
źródło
1
Zasadniczo widziałem drugi problem - identyczne hasła wyglądające inaczej - rozwiązany przez połączenie nazwy użytkownika, soli i hasła oraz zaszyfrowanie całego łańcucha. Eliminuje to konieczność generowania unikalnej soli na konto.
Justin Cave
1
@Justin: ciekawe, nigdy nie widziałem nazwy użytkownika używanej jako część skrótu, ale to naprawdę dobry sposób na dodanie entropii. Nadal używałbym pseudolosowej soli, tylko dlatego, że jej wytworzenie nie kosztuje dużo.
Matthieu M.
2
@ Matthieu Minusem jest to, że trzeba go gdzieś przechowywać, a jeśli obie strony potrzebują go, to także muszą go wysłać. Dzięki nazwie użytkownika obie strony już ją znają.
Matthew Frederick
2
@Justin: W takim przypadku używasz nazwy użytkownika jako soli. Odpowiada na oba cele soli: sprawienie, że tablice tęczowe są niepraktyczne, a podobne hasła wyglądają inaczej.
David Thornley
@David - Prawda, możesz spojrzeć na to, jak nazwa użytkownika staje się częścią soli. Nadal chciałbym dodatkowej soli, aby atakujący nie mógł użyć tęczowej tabeli do znalezienia kombinacji nazwy użytkownika / hasła. Bez wyraźnej soli, po prostu zwiększasz rozmiar ciągu, którego atakujący potrzebuje z tęczowej tabeli o długość nazwy użytkownika (która może być krótka i albo całkowicie mała, albo całkowicie duża). Stała sól wystarcza, aby udaremnić atak tęczowej tabeli, chyba że witryna jest wystarczająco duża, aby atakujący wygenerował tęczową tabelę.
Justin Cave
3

Za każdym razem, gdy chcesz zapisać nowe hasło (rejestracja, resetowanie hasła, aktualizacja hasła), jedną z dobrych technik jest:

  • generować nową sól
    • użyj kryptograficznie bezpiecznego generatora liczb pseudolosowych
    • użyj przyzwoitej wielkości soli - dobrą wartością jest rozmiar bloku bazowego algorytmu skrótu (może to być SHA-256)
  • wygeneruj nowy token hasła
    • utwórz funkcję hmac z bazowego algorytmu skrótu (może to być SHA-256), używając soli jako klucza hmac
    • for i in (0...65536) { password = hmac(password) }
    • wynikiem iteracji aplikacji funkcji hmac jest token hasła
  • przechowuj sól i token hasła
    • nie przechowuj oryginalnego hasła
    • opcjonalnie przechowuj podstawowy algorytm skrótu i ​​odcinki w celu wykrycia
yfeldblum
źródło
1

Wykorzystaj ramy. W .NET możesz użyć RNGCryptoServoiceProvider ...

        // If salt is not specified, generate it on the fly.
        if (saltBytes == null)
        {
            // Define min and max salt sizes.
            int minSaltSize = 4;
            int maxSaltSize = 8;

            // Generate a random number for the size of the salt.
            Random  random = new Random();
            int saltSize = random.Next(minSaltSize, maxSaltSize);

            // Allocate a byte array, which will hold the salt.
            saltBytes = new byte[saltSize];

            // Initialize a random number generator.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Fill the salt with cryptographically strong byte values.
            rng.GetNonZeroBytes(saltBytes); 
        }

Inne frameworki powinny mieć podobne klasy, które można wykorzystać. W celu osiągnięcia losowości oprogramowanie często zatrudnia użytkownika w porównaniu z Randompowyższym. Losowe przesuwanie myszy w określonym obszarze w celu dostarczenia soli jest opcją stosowaną przez TrueCrypt. Sprowadza się do twoich konkretnych potrzeb i poziomu bezpieczeństwa; ponieważ twoja sól może po prostu być !@#$%.

Aaron McIver
źródło
1

Generujesz solną stronę serwera i przypisujesz ją do konta użytkownika po jego utworzeniu. Lepiej użyj interfejsu API do generowania kryptografii dostępnego w twoim frameworku, ale w zasadzie wystarczy dowolna sekwencja.

Zwykle rzeczy są przechowywane w ten sposób:

User
-------------------
ID
Username
PasswordHashWithSalt

Przykład:

PasswordHashWithSalt =

A15CD9652D4F4A3FB61A2A422AEAFDF0DEA4E703 j5d58k4b56s8744q


źródło
Przypisać to na podstawie czego? Czy nie musi pochodzić z pewnej wartości, która pozostanie na miejscu, aby można ją było replikować, gdy użytkownik zaloguje się ponownie po utworzeniu?
Morgan Herlocker
Przez „przypisanie” mam na myśli wygenerowanie soli na parę nazwa użytkownika / hasło (konto) i zapisanie jej w bazie danych. Kiedy musisz się zalogować, używasz przechowywanej soli do sprawdzania rzeczy.
1

Użyj bcrypt i przeczytaj ten artykuł, ponieważ same zwykłe skróty nie stanowią poważnej ochrony w dzisiejszych czasach.

Rozważ użycie protokołu zerowej wiedzy hasła SDR, który ma wiele bibliotek typu open source i jest wolny od patentów.

SDR wymaga soli i najlepszym miejscem do zdobycia tego jest klient; czas ich naciśnięcia klawiszy, ruchy myszy, mieszanie zmiennych środowiskowych, liczby losowe, czasy tworzenia plików w folderze tymczasowym, aby uzyskać sól na ich końcu w nieprzewidywalny sposób z dala od serwera. SDR bierze sól, dużą liczbę pierwszą, hasło użytkownika i generuje klucz weryfikacyjny. Nie przechowujesz hasła, które nigdy nie opuszcza ich komputera, ale możesz sprawdzić, czy mają hasło, które zawiera klucz weryfikacyjny i sól. Jest odporny na ataki człowieka w środku i ataki słownikowe. Dla pewności zaszyfruj klucze i sól w kolumnie bazy danych.

simbo1905
źródło