Hash a password safely
Argon2id from the standard library — the right tool for passwords, without a single external dependency.
Passwords should never be stored in plaintext — nor with a fast hash like SHA-256. The standard library has Argon2id, which is made precisely for this.
bruk std.argon2id som argon2
funksjon start() -> heltall {
la passord = "et-langt-og-tilfeldig-passord"
la salt = builtin.random_hex(16)
la hash = argon2.hash(passord, salt)
skriv("Lagre denne, ikke passordet: " + hash)
hvis argon2.verify(passord, hash) {
skriv("Passordet stemmer")
} ellers {
skriv("Feil passord")
}
returner 0
}What happens here
You never store the password. You store the result of argon2.hash, and when the user logs in later, you run argon2.verify with what they typed against the stored value. Even with full access to your database, an attacker cannot get the passwords back out — only the ability to guess, one guess at a time.
The salt is random bytes that become unique per password. Without salt, two users with the same password would get the same hash, and an attacker could look up common passwords in a prebuilt table. With salt, each password must be attacked on its own. The builtin.random_hex function draws from a cryptographic randomness source — do not use an ordinary random generator for this.
Why Argon2id and not SHA-256
It seems backwards, but here speed is a disadvantage. SHA-256 is made to be fast, because it is meant to hash large files. That is exactly why it is terrible for passwords: an attacker with a graphics card can try billions of guesses per second.
Argon2id is made to be slow and memory-hungry on purpose. It can be tuned for how much time and memory each computation should cost. You barely notice it — the user waits a few hundred milliseconds at login — but it makes mass attacks thousands of times more expensive. Argon2id is moreover the variant that withstands both memory-tradeoff and side-channel attacks, and is the one you should choose when in doubt.
The right tool for the right job
The standard library also has BLAKE2b for ordinary hashes, and ChaCha20-Poly1305 for authenticated encryption. These are three different jobs:
- Password hash (Argon2id): one-way, deliberately slow, for values you should never get back.
- Ordinary hash (BLAKE2b): one-way, fast, for checksums and fingerprints.
- Encryption (ChaCha20-Poly1305): two-way, for data you will read again later.
Never use a password hash for encryption, or vice versa. It is one of the most common and most serious mistakes in homemade security code.
Related
- A web service with multiple routesA complete program that responds to several addresses, reads the query string and returns both HTML and plain text.
- Store and retrieve dataCreate a table, write rows and read them back out — with the built-in database functions, and without one query per row.
- Reading and writing filesFile handling with capabilities — and why your program cannot read what you have not given it.