sól
| Po angielsku | salt |
|---|---|
| Którą formą pisać | po polsku Polska nazwa przyjęła się w tekstach i w wyszukiwarce — używaj jej samodzielnie. |
| Inne formy | sól dynamiczna (poprawna odmiana pojęcia) · salt (tylko jako hasło wyszukiwania) |
| Kategoria | Kryptografia, tożsamość i uwierzytelnianie |
Sól to losowy, unikalny ciąg dodawany do każdego hasła w trakcie obliczania jego skrótu [1]. Przechowuje się ją razem ze skrótem, bo jest potrzebna przy każdej weryfikacji logowania [2]. Dzięki soli dwa identyczne hasła dają w bazie dwa różne skróty, a przygotowane zawczasu tablice skrótów tracą wartość [1]. Sól nie jest tajemnicą; jej zadaniem jest unikalność, nie poufność.
Jak działa
Serwis, który przechowuje hasła, nie powinien zapisywać ich jawnie ani szyfrować odwracalnie. Zapisuje wynik funkcji skrótu (hash), najlepiej wolnej, przeznaczonej do haseł. Przed obliczeniem skrótu do hasła dokleja się sól. Przy logowaniu serwer odczytuje sól zapisaną przy koncie, łączy ją z podanym hasłem, liczy skrót ponownie i porównuje wyniki. Proces pokazuje schemat poniżej.
NIST w wytycznych SP 800-63B wymaga, aby sól miała co najmniej 32 bity i była dobierana tak, by ograniczyć powtórzenia wartości wśród zapisanych skrótów [2]. Ten sam dokument wymaga przechowywania dla każdego hasła zarówno soli, jak i wynikowego skrótu [2]. MITRE zaleca generowanie nowej soli dla każdego hasła silnym generatorem liczb losowych i przestrzega przed używaniem tej samej soli dla wszystkich haseł [3].
W praktyce programista rzadko losuje sól sam. OWASP zauważa, że nowoczesne algorytmy, takie jak Argon2id, bcrypt i PBKDF2, wymagają soli, ale ich implementacje zwykle generują ją i zarządzają nią wewnętrznie [1]. Sól zostaje wtedy zapisana w tym samym ciągu co skrót.
Rodzaje
Polska literatura branżowa odróżnia sól statyczną od dynamicznej. Sekurak opisuje sól statyczną jako stałą wartość dodawaną do każdego hasła, a sól dynamiczną jako nieprzewidywalny ciąg dodawany osobno do każdego hasła [4]. Tylko druga odpowiada definicji tego hasła. Obok soli stosuje się czasem pieprz (pepper), który działa inaczej.
| Mechanizm | Czy unikalny | Gdzie przechowywany | Przed czym chroni |
|---|---|---|---|
| sól dynamiczna | tak, dla każdego hasła [3] | razem ze skrótem [2] | tablicami gotowych skrótów, porównaniem identycznych haseł [1] |
| sól statyczna | nie, jedna dla wszystkich [4] | w kodzie lub konfiguracji | praktycznie przed niczym [4] |
| pieprz | wspólny dla wielu haseł [1] | poza bazą, np. w sejfie sekretów lub HSM [1] | wyciekiem samej bazy danych [1] |
Sekurak tłumaczy, dlaczego sól statyczna zawodzi: atakujący, który przełamie zabezpieczenia, poznaje ją i dokleja do każdego sprawdzanego ciągu [4]. Pieprz jest według OWASP dodatkową warstwą ochrony na wypadek wycieku samej bazy i nie powinien być przechowywany razem ze skrótem [1].
W WordPressie
WordPress soli hasła automatycznie. Funkcja wp_hash_password() przez lata używała biblioteki phpass; dokumentacja opisuje ją jako mechanizm, który dodaje sól i wykonuje 256 przebiegów MD5 [7]. Od wersji 6.8 hasła użytkowników są domyślnie haszowane algorytmem bcrypt przez funkcję PHP password_hash() [7], która sama generuje sól dla każdego hasła [1]. Nowe skróty mają prefiks $wp$2y$, żeby odróżnić je od zwykłych skrótów bcrypt tworzonych przez wtyczki [6]. Stare skróty nadal działają i są przeliczane przy następnym logowaniu użytkownika albo zmianie hasła [6].
Bcrypt przyjmuje najwyżej 72 bajty danych, dlatego WordPress najpierw liczy skrót SHA-384 z hasła [6]. Hasła aplikacji (application passwords), klucze resetu hasła i klucz trybu odzyskiwania przeszły w tej samej wersji na szybki algorytm BLAKE2b z biblioteki Sodium [6].
Nazwa „sól” pojawia się w WordPressie także w innym znaczeniu. Stałe AUTH_SALT, LOGGED_IN_SALT i NONCE_SALT z pliku wp-config.php nie są solami zapisywanymi przy skrótach haseł użytkowników, tylko losowymi sekretami całej witryny. Dokumentacja podaje, że cztery sole są zalecane, ale nie wymagane, bo w razie ich braku WordPress wygeneruje je sam [8]. Zmiana kluczy i soli unieważnia wszystkie istniejące ciasteczka i wymusza ponowne logowanie [8]. Opisuje je osobne hasło klucze bezpieczeństwa i sole; o ochronie samego pliku mówi utwardzanie pliku wp-config.php.
Znaczenie
Bez soli dwa konta z tym samym hasłem mają w bazie ten sam skrót. Po wycieku danych atakujący od razu widzi, które hasła się powtarzają, i może sprawdzić miliony z nich jednym przebiegiem słownika. MITRE opisuje brak soli jako słabość CWE-759, która ułatwia przygotowanie skrótów zawczasu technikami słownikowymi, na przykład tęczowymi tablicami [3]. OWASP podkreśla, że przy unikalnej soli trzeba łamać każdy skrót osobno, więc czas pracy rośnie wprost proporcjonalnie do ich liczby [1].
Sól nie czyni słabego hasła silnym. MITRE zaznacza, że nie zmniejsza ona pracy potrzebnej do ataku na pojedynczy skrót, a współczesne ataki liczą ogromne liczby skrótów równolegle [3]. Dlatego sól musi iść w parze z wolnym algorytmem, najlepiej z funkcją wyprowadzania klucza, czyli KDF. Łamanie haseł metodą ataku siłowego (brute-force) na dobrze posolonym skrócie bcrypt nadal jest możliwe, ale kosztowne.
Dobre praktyki
- Używać gotowego algorytmu do haseł. OWASP rekomenduje Argon2id z parametrami m=19456, t=2, p=1; bcrypt z czynnikiem pracy co najmniej 10 wskazuje dla systemów starszych, a PBKDF2-HMAC-SHA256 z co najmniej 600 000 iteracji tam, gdzie wymagany jest FIPS-140 [1].
- Nie projektować własnego schematu soli. W WordPressie korzystać z
wp_hash_password()iwp_check_password(), zamiast liczyć skróty w kodzie wtyczki. - Nie używać jednej soli dla wszystkich kont [3].
- Traktować sól jako dane publiczne, a sekrety, takie jak pieprz, trzymać poza bazą [1].
- Zachęcać do długich, unikalnych haseł; zob. bezpieczne hasła i menedżer haseł.
Historia i przykłady
MITRE jako przykłady słabości CWE-759 podaje CVE-2008-1526 i CVE-2006-1058, w obu przypadkach routery, które nie używały soli przy skrótach haseł [3]. Pouczający jest też przypadek serwisu Formspring. Niebezpiecznik 12 lipca 2012 roku opisał wyciek około 420 tysięcy skrótów SHA-256 z tego serwisu [5]. Sól przyjmowała tylko 100 wartości, od 00 do 99, więc atakującemu wystarczyło przygotować 100 osobnych słowników [5]. Formspring wymusił zmianę haseł i zapowiedział przejście na bcrypt [5]. Przykład pokazuje, że sól o małej liczbie możliwych wartości działa niewiele lepiej niż sól statyczna.
Przypisy
8- [1] Password Storage Cheat Sheet · OWASP
- [2] NIST SP 800-63B-4: Digital Identity Guidelines — Authentication and Authenticator Management · NIST
- [3] CWE-759: Use of a One-Way Hash without a Salt · MITRE
- [4] Kompendium bezpieczeństwa haseł – atak i obrona (część 3.) · Sekurak
- [5] Ciekawy wyciek 420 000 hashy haseł z serwisu Formspring · Niebezpiecznik
- [6] WordPress 6.8 will use bcrypt for password hashing · WordPress.org
- [7] wp_hash_password() — Code Reference · WordPress.org
- [8] wp-config.php — Common APIs Handbook · WordPress.org