Security Wiki
A concise reference on passwords, hashing, encoding, and modern security practices. No jargon, just what you need to know.
π Passwords and passphrases
A password is a secret string of characters used to prove identity or protect access to a resource. A passphrase is a longer sequence of words, often with separators or numbers, designed to be easier for humans to remember while remaining hard for computers to guess.
Character-based passwords
These are the traditional strings built from a character pool: uppercase letters, lowercase letters, digits, and special symbols. Their strength depends on two factors: length and pool size (how many different characters are allowed).
A 12-character password using uppercase, lowercase, and digits has a pool of 62 characters. The total number of possible combinations is 6212, which is roughly 3.2 Γ 1021.
Passphrases (XKCD-style)
Popularized by the XKCD comic "Password Strength," a passphrase combines random dictionary words. For example: correct-horse-battery-staple. The idea is that four common words, chosen randomly from a pool of a few thousand, can produce enormous entropy while being memorable.
logβ(7776β΄) β 51.7 bits of entropy β stronger than most 8-character complex passwords.
When to use which
| Scenario | Recommended | Why |
|---|---|---|
| Website login | Passphrase or password manager | Easy to type, easy to remember |
| API key / token | Random 32+ character string | No human needs to remember it |
| Database password | Random 20+ character string | High entropy, stored in config |
| Wi-Fi network | Passphrase or long random string | Shared, needs to be typed once |
π² Entropy and password strength
Entropy is a measure of randomness, expressed in bits. In password security, it tells you how many guesses an attacker would need to make, on average, to find your password by brute force.
The formula
E = L Γ logβ(R)
Where E is entropy in bits, L is length, and R is the size of the character pool. For example, a 16-character password using 62 possible characters has 16 Γ logβ(62) β 95 bits of entropy.
Entropy benchmarks
| Entropy | Strength | Typical crack time* |
|---|---|---|
| < 28 bits | Very weak | Seconds to minutes |
| 28β35 bits | Weak | Minutes to hours |
| 36β60 bits | Moderate | Hours to years |
| 60β80 bits | Strong | Years to centuries |
| 80β128 bits | Very strong | Centuries to millennia |
| > 128 bits | Overkill | Effectively forever |
* Assumes 100 trillion guesses per second (modern GPU cluster). Real-world attacks are usually much slower due to rate limiting and hashing costs.
π Universally unique identifiers (UUID)
A UUID (Universally Unique Identifier) is a 128-bit number used to identify information in computer systems. The goal is not secrecy β it is uniqueness. The chance of two properly generated UUIDs colliding is astronomically low.
UUID versions
| Version | Method | Use case |
|---|---|---|
| UUIDv1 | Timestamp + MAC address | Ordered, but leaks MAC address |
| UUIDv3 | MD5 hash of a namespace + name | Deterministic (same input = same UUID) |
| UUIDv4 | Random 122 bits | Most common; fully random |
| UUIDv5 | SHA-1 hash of a namespace + name | Deterministic, stronger than v3 |
| UUIDv6 | Reordered timestamp (like v1 but sortable) | Databases needing time-sortable IDs |
| UUIDv7 | Unix timestamp + random | Time-ordered, privacy-safe, sortable |
| UUIDv8 | Custom format | Experimental / vendor-specific |
When to use UUIDs
- Database primary keys: Avoids exposing sequential IDs and simplifies distributed systems.
- API tokens / session IDs: As long as they are not the sole security factor.
- File names: Prevents collisions when uploading files from multiple users.
- Transaction IDs: Traceable across microservices without a central counter.
π Cryptographic hashing
A hash function takes an input of any size and produces a fixed-size output called a digest. A cryptographic hash function has four critical properties:
- Deterministic: The same input always produces the same output.
- One-way: It is computationally infeasible to reverse the hash back to the original input.
- Avalanche effect: A tiny change in input produces a completely different output.
- Collision-resistant: It is extremely unlikely that two different inputs produce the same output.
Common hash algorithms
| Algorithm | Output size | Status | Use case |
|---|---|---|---|
| MD5 | 128 bits | Broken | Legacy only; never for security |
| SHA-1 | 160 bits | Deprecated | Legacy; being phased out |
| SHA-256 | 256 bits | Secure | Data integrity, certificates, Bitcoin |
| SHA-512 | 512 bits | Secure | High-security environments |
| SHA-3 (Keccak) | Variable | Secure | Next-gen standard |
| BLAKE2b | Variable | Secure | Fast, modern alternative to SHA |
| BLAKE3 | 256 bits | Secure | Extremely fast, parallelizable |
Hashing for password storage
Plain hash functions like SHA-256 are not suitable for storing passwords. They are too fast. An attacker with a GPU can test billions of passwords per second.
For passwords, you need a slow hash function:
- bcrypt: Adaptive cost factor. The standard for many years.
- scrypt: Memory-hard. Resistant to GPU and ASIC attacks.
- Argon2: Winner of the Password Hashing Competition (2015). Memory-hard, tunable, modern standard.
- PBKDF2: Older, still acceptable with high iteration counts (β₯ 600,000).
π Encoding and decoding
Encoding transforms data from one format to another. It is not encryption β there is no secret key, and anyone can reverse it. Encoding is about compatibility and transport, not security.
Common encoding schemes
| Scheme | Purpose | Example |
|---|---|---|
| Base64 | Binary β ASCII text | SGVsbG8gV29ybGQ= |
| Base32 | Binary β uppercase AβZ + 2β7 | JBSWY3DPEBLW64TMMQ====== |
| Base16 (Hex) | Binary β 0β9, AβF | 48656c6c6f20576f726c64 |
| URL encoding | Safe transport in URLs | Hello%20World |
| HTML entities | Safe display in HTML | <div> |
When to use encoding
- Base64: Embedding images in CSS/HTML, sending binary data in JSON, email attachments (MIME).
- Hex: Displaying hash digests, representing raw bytes in a readable form.
- URL encoding: Passing special characters in query parameters or form data.
ποΈ Key derivation functions
A Key Derivation Function (KDF) takes a password (or any low-entropy input) and stretches it into a high-entropy cryptographic key. KDFs are deliberately slow and memory-intensive to resist brute-force attacks.
How they work
A KDF applies a hash function thousands or millions of times, often with a salt and memory-hard operations. This means:
- Legitimate users wait a fraction of a second.
- Attackers must spend the same fraction of a second per guess, making large-scale brute force prohibitively expensive.
Types of KDFs
| KDF | Properties | Best for |
|---|---|---|
| PBKDF2 | CPU-hard, iterative | Legacy systems, high iteration counts |
| bcrypt | CPU-hard, adaptive cost | Password hashing (β€ 72 byte input) |
| scrypt | Memory-hard | Crypto wallets, resistant to ASICs |
| Argon2id | Memory-hard, tunable | Modern password hashing (recommended) |
m=47104 (46 MiB memory), t=1 iteration, and p=1 parallelism for general use. Adjust based on your server's capacity.
π§ Salt, pepper, and why they matter
When two users choose the same password, their hashes will be identical unless you add randomness. Salt and pepper solve this.
Salt
A salt is a random string unique to each password, appended (or prepended) before hashing. It ensures that even identical passwords produce different hashes. Salts are stored alongside the hash in the database.
hash = bcrypt(password + salt)
Without salt, an attacker can pre-compute hashes for common passwords (rainbow tables) and instantly crack any match. With salt, every password must be attacked individually.
Pepper
A pepper is a secret key stored outside the database (e.g., in an environment variable or HSM). It is combined with the password before hashing, but unlike salt, it is the same for all users and never stored with the hashes.
hash = bcrypt(password + salt + pepper)
If the database is leaked but the pepper is not, the attacker cannot crack any password without also obtaining the pepper.
β‘ How passwords are cracked
Understanding attack methods helps you appreciate why length, entropy, and slow hashing matter.
Brute force
Trying every possible combination of characters. A 6-character lowercase password has 26βΆ = 308 million combinations. A modern GPU can test this in seconds. A 12-character mixed password has 62ΒΉΒ² β 3 Γ 10Β²ΒΉ combinations β impossible to brute force.
Dictionary attack
Instead of random characters, the attacker tries words from a dictionary. password123 and qwerty fall instantly. Even CorrectHorseBatteryStaple is vulnerable if the attacker knows you use XKCD-style passphrases and has the same wordlist.
Rainbow tables
Pre-computed tables mapping hashes to plaintext passwords. Defeated entirely by salting, because each salt requires a new table.
Credential stuffing
Using username/password pairs leaked from one breach to log into other services. Works because people reuse passwords. Defeated by unique passwords per service.
Social engineering
Tricking a human into revealing a password. No amount of entropy protects against this. Defeated by security awareness and 2FA.
π‘οΈ Two-factor and multi-factor authentication
2FA requires two different types of evidence to prove identity. MFA extends this to two or more. The three categories of factors are:
- Something you know: Password, PIN, security question.
- Something you have: Phone, hardware key, smart card.
- Something you are: Fingerprint, face scan, iris pattern.
Common 2FA methods
| Method | Security | Convenience |
|---|---|---|
| SMS code | Weak (SIM swap attacks) | High |
| TOTP app (Google Authenticator, Authy) | Strong | High |
| Push notification | Medium (phishable) | Very high |
| Hardware key (YubiKey, FIDO2) | Very strong | Medium |
| Passkeys (WebAuthn) | Very strong | High |
π Password managers
A password manager generates, stores, and autofills passwords. You only need to remember one strong master password. The manager handles the rest.
Why use one
- Unique passwords: Every account gets a different, random password.
- Strong passwords: No need to remember them, so they can be 30+ characters.
- Phishing resistance: Managers only autofill on the correct domain.
- Audit: Detect reused or breached passwords.
Types
| Type | Examples | Pros | Cons |
|---|---|---|---|
| Cloud-based | Bitwarden, 1Password | Sync across devices, easy recovery | Trust the vendor |
| Self-hosted | Vaultwarden, Passbolt | Full control, open source | Setup and maintenance |
| Offline | KeePassXC | No cloud, fully offline | Manual sync between devices |
| Browser built-in | Chrome, Firefox, Safari | Zero friction | Less flexible, tied to browser |
β Best practices checklist
- Use a password manager and let it generate passwords for you.
- Every account gets a unique password. Never reuse.
- Passwords should be at least 16 characters long, or use a 4+ word passphrase.
- Enable 2FA on every account that supports it.
- Prefer TOTP or hardware keys over SMS for 2FA.
- Store passwords with Argon2id, bcrypt, or scrypt β never MD5 or plain SHA.
- Always use a unique salt per password. Consider a pepper for extra defense.
- Never transmit passwords over unencrypted HTTP. Always use HTTPS/TLS.
- Implement rate limiting and account lockouts on login forms.
- Monitor for breached credentials using services like Have I Been Pwned.
- Rotate passwords after a confirmed breach, not on a fixed schedule.
- Never store passwords in plain text, in logs, or in version control.