Duże litery, małe litery, cyfry i znaki specjalne, czyli standard w hasłach 🤔
Rekomendacje mówią, aby tego nie robić, ale programiści i tak wiedzą swoje
"Te wymagania mają sens i pomagają początkującym użytkownikom. Nie każdy korzysta z Keepassa!".
Co robić? Jak żyć? 🧵 ↓
Zacznijmy od absolutnych podstaw.
Zagrożenie, przed którym się bronimy, to NIE jest naparzanie przez hackera losowymi hasłami w ekran logowania, bo a nuż zgadnie.
Problemem jest wyciek bazy danych, która prawdopodobnie i tak jest hashowana.
Pomimo stosowania mocnych algorytmów hashujących, po wycieku bazy danych, agresor i tak podejmie próbę złamania słabych hashy i zdobycia znajdujących się tam haseł.
Jeśli hasło było słabe, to je przejmie i przeprowadzi atak credential stuffing w popularnych serwisach.
Ale jak literki, cyferki i znaki specjalne mają to niby utrudnić?
Tutaj wchodzi matematyka. Istnieje coś takiego jak współczynnik entropii, który wyraża, jak bardzo nieprzewidywalne jest hasło.
Jest na to nawet wzór:
Entropia = N x log2(R)
Nie martw się, już wyjaśniam wzór!
We wzorze mamy dwa elementy:
• N = liczba znaków hasła
• R = pula znaków, z których wybierane są znaki hasła
Jeśli użytkownik ma hasło "basia", to pulą jest 26 znaków (litery a-z).
Dla hasła "basia" entropia wynosi:
E = 5 x log2(26) = około 23,5
Czyli słabiutko 😕
Za dobre hasło w zależności od źródeł uznaje się coś z entropią od 56 / 70 w górę.
Jak zwiększyć ten wynik?
Mamy dwa parametry, więc możemy pani Basi powiedzieć:
↳ Proszę wpisać dłuuuuugie hasło
↳ musi Pani zwiększyć pulę potencjalnych znaków zdatnych do użycia w haśle.
Druga instrukcja może być trochę niezrozumiała 😉
W praktyce, drugie polecenie oznacza, że musimy wyjść poza zakres liter "a-z".
Już samo napisanie słowa "Basia" dużą literą rozszerza bazowy zestaw znaków [a-z] z 26 do 52 znaków [a-zA-Z], co doprowadza nas do zwiększenia bitów entropii z 23 do 28, czyli hasło nadal jest 💩
Aleee! Jeśli poprosimy Basię o dopisanie cyfry (dodatkowy przedział 10 znaków) oraz znaku specjalnego (+43 znaki) oraz dużej litery, a przy okazji wymusimy 10 liter w haśle, to mamy entropię na poziomie:
E = 10 x log2(26+26+10+33) = około 65
Całkiem znośne hasło! 🙂
Tylko to tak ładnie wygląda jedynie we wzorze, bo w praktyce Pani Basia ustawi hasło w stylu:
↳ Basiaaaa1!
A jak ją poprosimy o regularną, comiesięczną zmianę, to wyjdzie nam:
↳ Basiaaaa2!
↳ Basiaaaa3!
↳ Basiaaaa4!
Wymogi dodatkowych znaków w haśle i minimalna długość podnoszą bezpieczeństwo - matematyki nie oszukam.
Takie hasła będą jednak zazwyczaj skrajnie proste, z małą różnorodnością, a do tego jest ryzyko, że Basia je zapisze np. na kartce, bo przecież nie zapamięta 🤷♂️
To jak wymusić na użytkowniku mocne hasło?
Gdybyśmy tylko znali jakiś wzór na to... 🤔
O! Wiem ⬇️
Mamy wzór, to co robimy jako programista?
1. Pobierasz od użytkownika proponowane hasło
2. Liczysz, ile ma znaków i zapisujesz to w zmiennej N
3. Sprawdzasz, jakiego zakresu znaków używa user
4. Wrzucasz wszystko do wzoru
5. Wynik poniżej np. 70? "Twoje hasło jest za słabe"
No dobra, ale jak wykonać punkt 3 z tym liczeniem znaków?
wynik = 0
if (mala_litera) wynik += 26;
if (duza_litera) wynik += 26;
if (cyfra) wynik += 10;
if (znak_specjalny) wynik += 33;
return wynik;
OK i co nam to daje?
Basia chce mieć hasło "kot"
Poziom entropii = 14
"Twoje hasło jest zbyt łatwe do złamania.
Dopisz proszę coś do niego, aby było dłuższe. Możesz np. ułożyć jakieś zdanie."
Basia przechodzi więc przez kolejne kroki:
↳ kotkot = 28
↳ za słabe!
↳ lubiekoty = 42
↳ za słabe!
↳ mamczteryrudekoty = 79
↳ Barbara! Jestem z Ciebie dumny! Mraaau 😻
Przy klasycznym podejściu i haśle spełniającym wymogi poziomu skomplikowania (duże litery, małe, cyfry itd), Basia osiągnęła moc hasła równą 65 bitów. Do tego ma trudne do zapamiętania hasło:
Basiaaaa1!
- Ile było tych liter 'a'?
- jaka to była cyfra i znak?
Stosując proste polecenie "Twoje hasło jest za słabe" połączone z jakąś podpowiedzią np. "zbuduj zdanie, które na pewno zapamiętasz", Basia uzyskała 79 bitów entropii i hasło, którego jako kociara nigdy nie zapomni 😉
mamczteryrudekoty
P.S zapis ze spacjami to 94 bity!
Stosowanie klasycznego podejścia z zestawem znaków i długością hasła doprowadza nas do patologii tego typu 👇
Hasło: Superm3n$
Basia! Super hasło! tak trzymaj! 👏 [E=55]
Hasło: NaWakacjęPojadęDoWłoch
Barbara 🤦♂️ No, z czym do ludzi! Weź to zmień... [E=125]
Implementacja liczenia entropii w kodzie jest łatwa, zarówno po stronie frontendu, jak i backendu. UX dla usera jest przyjaźniejszy, a wygenerowane hasło prostsze do zapamiętania, aleee!
Nie musisz tego wszystkiego implementować samodzielnie.
Gotowiec: github.com/dropbox/zxcvbn
Oczywiście, ideałem byłoby, aby każdy użytkownik korzystał z menadżera haseł i kolejnej warstwy zabezpieczeń (jakieś 2FA), ale nie mamy bezpośredniego wpływu na edukację użytkownika w branży cybersec i nie kupimy Basi pary kluczy U2F.