Generator haseł
Generuj silne, losowe hasła z dowolną długością i zestawami znaków
Czym jest generator haseł?
Generator haseł tworzy losowe ciągi znaków używane jako hasła do kont użytkowników, kluczy API, danych uwierzytelniających do baz danych i sekretów szyfrowania. W przeciwieństwie do haseł wybieranych przez człowieka, generowane hasła czerpią z pełnej przestrzeni możliwych kombinacji znaków, co czyni je odpornymi na ataki słownikowe i zgadywanie oparte na wzorcach. Narzędzie generuje silne, losowe hasła online, korzystając z wbudowanego kryptograficznego generatora liczb losowych przeglądarki.
Siła hasła zależy od dwóch czynników: długości i różnorodności znaków. Hasło składające się z 20 znaków, zawierające wielkie i małe litery, cyfry oraz symbole, ma około 131 bitów entropii. Na tym poziomie atak brute-force testujący bilion zgadnięć na sekundę potrzebowałby więcej czasu niż wiek wszechświata, aby sprawdzić każdą kombinację. Matematyka jest prosta: entropia = długość × log2(rozmiar zestawu znaków).
Standardy takie jak NIST SP 800-63B zalecają hasła o długości co najmniej 8 znaków bez górnego limitu narzucanego przez weryfikatora i odradzają wymuszanie reguł kompozycji, takich jak wymaganie dokładnie jednego symbolu, preferując zamiast tego dłuższe frazy hasłowe. W przypadku danych uwierzytelniających między maszynami i kont serwisowych, 20 lub więcej losowych znaków z pełnego zestawu znaków to akceptowana podstawa w większości ram bezpieczeństwa i reżimów zgodności.
Dlaczego warto używać generatora haseł?
Ludzie są słabymi generatorami liczb losowych. Używamy tych samych haseł wielokrotnie, wybieramy słowa ze słownika, zastępujemy litery przewidywalnymi wzorcami (@ zamiast a, 3 zamiast e) i domyślnie stosujemy krótkie ciągi znaków. Generator haseł eliminuje ludzkie uprzedzenia z tego procesu.
Zastosowania generatora haseł
Tabela entropii haseł
Entropia mierzy, jak nieprzewidywalne jest hasło. Oblicza się ją jako log2(rozmiar_zestawu_znaków ^ długość). Wyższa entropia oznacza więcej możliwych kombinacji, które atakujący musi przeszukać. NIST i OWASP zalecają co najmniej 80 bitów entropii dla aplikacji o wysokim poziomie bezpieczeństwa.
| Długość | Zestaw znaków | Entropia | Czas ataku brute-force |
|---|---|---|---|
| 8 | lower + digits | ~41 bits | Minutes to hours |
| 12 | lower + upper + digits | ~71 bits | Centuries (offline) |
| 16 | all character sets | ~105 bits | Beyond brute-force |
| 20 | all character sets | ~131 bits | Beyond brute-force |
| 32 | all character sets | ~210 bits | Beyond brute-force |
| 64 | all character sets | ~419 bits | Beyond brute-force |
Czasy łamania zakładają bilion zgadnięć na sekundę (atak offline z nowoczesnymi GPU). Ataki online z ograniczaniem liczby żądań są o rzędy wielkości wolniejsze.
CSPRNG vs Math.random() w generowaniu haseł
Źródło losowości ma równie duże znaczenie jak długość hasła. Hasło wygenerowane za pomocą przewidywalnego generatora liczb losowych może zostać odtworzone przez atakującego, który zna algorytm i stan ziarna. Narzędzie używa crypto.getRandomValues(), czyli kryptograficznie bezpiecznego pseudolosowego generatora liczb (CSPRNG) wbudowanego w każdą nowoczesną przeglądarkę.
Przykłady kodu
Generuj hasła programowo w różnych językach. Każdy poniższy przykład używa kryptograficznie bezpiecznego źródła losowości, a nie Math.random() ani równoważnych słabych PRNG.
// Generate a random password in the browser or Node.js 19+
function generatePassword(length = 20) {
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
const values = new Uint32Array(length)
crypto.getRandomValues(values)
return Array.from(values, v => charset[v % charset.length]).join('')
}
console.log(generatePassword()) // → "kR7!mZp$Xw2&nLq9@Yf3"
console.log(generatePassword(32)) // → "Hd4%tNx!Qw8#mKp2Rv6&Zj0*Ls3Yb7@"import secrets
import string
def generate_password(length: int = 20) -> str:
"""Generate a cryptographically secure random password."""
alphabet = string.ascii_letters + string.digits + string.punctuation
return ''.join(secrets.choice(alphabet) for _ in range(length))
# Single password
print(generate_password()) # → "kR7!mZp$Xw2&nLq9@Yf3"
# Batch of 5 passwords
for _ in range(5):
print(generate_password(24))
# Ensure at least one char from each category
def generate_strong(length: int = 20) -> str:
required = [
secrets.choice(string.ascii_uppercase),
secrets.choice(string.ascii_lowercase),
secrets.choice(string.digits),
secrets.choice(string.punctuation),
]
remaining = length - len(required)
alphabet = string.ascii_letters + string.digits + string.punctuation
all_chars = required + [secrets.choice(alphabet) for _ in range(remaining)]
secrets.SystemRandom().shuffle(all_chars)
return ''.join(all_chars)# OpenSSL — generate 32 random bytes, base64-encode openssl rand -base64 32 # → "x7Kp2mNqR4wZ8vLs1Yb0Hd6tFj3Xc9Ga5eUi+Wo=" # /dev/urandom with tr — alphanumeric + symbols, 20 chars tr -dc 'A-Za-z0-9!@#$%^&*' < /dev/urandom | head -c 20; echo # → "kR7!mZp$Xw2&nLq9@Yf3" # pwgen (install: apt install pwgen / brew install pwgen) pwgen -sy 20 5 # Generates 5 passwords, 20 chars each, with symbols
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func generatePassword(length int) (string, error) {
charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"
result := make([]byte, length)
for i := range result {
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
return "", err
}
result[i] = charset[idx.Int64()]
}
return string(result), nil
}
func main() {
pwd, _ := generatePassword(20)
fmt.Println(pwd) // → "kR7!mZp$Xw2&nLq9@Yf3"
}