Właściwy generator,
właściwy język.
Nie wszystkie generatory haseł są sobie równe — a język, w którym napisano Twój sejf, nie jest tylko szczegółem inżynierskim. Wyjaśniamy entropię, tryby generowania i to, dlaczego Rust coraz częściej trafia pod maskę.
Gdy menedżer “generuje silne hasło”, pojawiają się dwa pytania: czy naprawdę jest ono nieprzewidywalne (jakość losowości) oraz co dzieje się z nim w pamięci po wyświetleniu? Pierwsze zależy od trybów generowania. Drugie od języka, w którym działa aplikacja. Ten artykuł omawia oba aspekty.
01 / PODSTAWYEntropia: jedyna miara, która ma znaczenie
Siły hasła nie mierzy się odczuwaną “złożonością”, lecz jego entropią: liczbą bitów niepewności dla atakującego. Im więcej możliwych kombinacji, tym gwałtowniej rośnie koszt ataku brute-force. Hasło o długości 16 znaków wybranych z pełnego alfabetu ASCII osiąga około 100 bits — czyli poziom “bardzo silny”.
Kluczowy, często pomijany punkt: entropia ma wartość tylko wtedy, gdy źródłem losowości jest CSPRNG (kryptograficznie bezpieczny generator pseudolosowy). Klasyczne Math.random() jest przewidywalne i dyskwalifikuje całą resztę. Dobre implementacje pobierają entropię z systemu operacyjnego: /dev/urandom lub getrandom(2) w Unix, CNG w Windows.
02 / TRYBYCztery rodziny generatorów
Dobry menedżer nie oferuje “jednego” generatora, lecz kilka trybów dopasowanych do zastosowania. Zasada brzmi: łatwość zapamiętania kosztuje długość. Oto cztery rodziny, od najbardziej zwartej do najbardziej przyjaznej człowiekowi.
Czysto losowe
j7$kQ!mP2#xR9vL@Passphrase (Diceware / EFF)
Granite-Bicycle-Phantom-Violet-9Zapamiętywalne / wymawialne
Crimson7!Falcon$ReefNumeryczny PIN
8392 4471Dobry odruch: dopasować entropię do zastosowania
Dla konta internetowego chronionego przez stronę logowania z ograniczeniem tempa atakujący jest przyhamowany do kilkuset prób na sekundę: nawet 50 bits wytrzymuje wtedy geologiczne skale czasu. Nadmiar entropii ma sens przede wszystkim dla sekretów offline (klucz szyfrujący, seed portfela crypto), gdzie atak można masowo zrównoleglić. Dla sekretów o bardzo wysokiej wartości rzucanie prawdziwymi fizycznymi kośćmi (Diceware w dosłownym sensie) pozostaje opcją ostateczną: eliminuje zależność od jakości CSPRNG albo od skompromitowanej przeglądarki.
03 / POD MASKĄDlaczego Rust zmienia reguły gry
Wygenerowanie dobrego hasła to połowa pracy. Druga połowa: nie pozwolić mu zalegać. Po wyświetleniu lub odszyfrowaniu hasło żyje w pamięci RAM — i właśnie tam język aplikacji staje się decydujący.
Microsoft informował, że 70 % podatności bezpieczeństwa, z którymi się spotyka, to błędy pamięci (buffer overflow, use-after-free itd.). Google zaobserwowało tę samą proporcję w Chrome i Android. To dokładnie te klasy błędów, które Rust eliminuje na etapie kompilacji dzięki modelowi własności (ownership) i pożyczania (borrowing), bez garbage collector.
Dane Google są wymowne: podatności pamięci w Android spadły z 223 w 2019 do mniej niż 50 w 2024, po raz pierwszy schodząc poniżej 20 % całości. Nowy kod Rust wykazuje gęstość błędów pamięci nawet 1000× niższą niż historyczny kod C/C++, a dodatkowo 4× mniej rollbacków i 25 % krótszy czas review.
1. Bezpieczeństwo pamięci bez garbage collector. Języki takie jak Java czy Python są memory-safe, ale ich garbage collector zwalnia pamięć niedeterministycznie: sekret może przetrwać w niej bezterminowo, narażony na memory dump lub atak cold-boot. Rust zwalnia pamięć deterministycznie, gdy dane przestają być używane.
2. Jawne wymazywanie przez zeroize. Rust nie gwarantuje, że zwolniona pamięć zostanie nadpisana. Crate zeroize wypełnia tę lukę: opakowanie sekretu w Zeroizing gwarantuje nadpisanie go zerami — przez volatile write, którego kompilator nie może zoptymalizować — dokładnie w chwili, gdy wychodzi poza zakres.
3. System typów, który wymusza właściwe użycie crypto. Ścisły system typów Rust pozwala ograniczyć, jak dane wrażliwe mogą być używane — i ile razy. Można na przykład zamodelować klucz, którego wolno użyć tylko raz; kompilator odrzuci każde ponowne użycie.
Automatyczne wymazywanie w pamięciuse zeroize::Zeroizing;
fn unlock_vault(master: &str) {
let dek = Zeroizing::new(derive_key(master));
// ... déchiffrement du coffre ...
} // `dek` est écrasé par des zéros ici, automatiquementPODATNOŚCI PAMIĘCI — ANDROID (% CAŁOŚCI)
ADOPCJA RUST
Techniczna uczciwość: Rust nie jest magiczną różdżką
Kod unsafe i zależności zewnętrzne nadal pozostają powierzchnią ataku — Google naprawiło zresztą lukę (CVE-2025-48530) w bloku unsafe parsera Rust przed wdrożeniem produkcyjnym. Bezpieczeństwo pamięci to warstwa, nie cel sam w sobie: łączy się z defense in depth (solidny KDF taki jak Argon2id, architektura zero-knowledge, automatyczne blokowanie, MFA).
Język z garbage collector
- Niedeterministyczne zwalnianie pamięci
- Sekrety pozostają w pamięci przez nieznany czas
- Jawne wymazywanie trudne albo niemożliwe
- Narażenie na dumps & cold-boot
Rust
- Deterministyczne zwalnianie (ownership)
- Natychmiastowe wymazywanie przez zeroize
- Brak buffer overflow i use-after-free
- Błędy crypto wychwytywane podczas kompilacji
04 / DO ZAPAMIĘTANIACzego wymagać od menedżera
Przy wyborze — lub ocenie — menedżera haseł warto zadać cztery konkretne pytania:
Checklist
- 1. Czy generator opiera się na systemowym CSPRNG i pokazuje entropię w bits?
- 2. Czy oferuje tryb passphrase Diceware/EFF dla hasła głównego?
- 3. Czy generowanie odbywa się lokalnie (client-side), bez przechodzenia przez serwer?
- 4. Czy wrażliwy rdzeń jest napisany w języku memory-safe z jawnym wymazywaniem sekretów?
Bezpieczne generowanie. Sejf zaprojektowany na lata.
Hasła o wysokiej entropii, zapamiętywalne passphrases i rdzeń zbudowany z myślą o bezpieczeństwie pamięci.
Poznaj nasze podejście