What is a Hash?
A hash function takes any input — a word, a password, a gigabyte file — and produces a fixed-size string of bytes called a digest. Three properties make it useful:
- One-way. Easy to compute; designed to make finding an input for a given digest infeasible. A short list of likely inputs can still be tried.
- Deterministic. The same input always yields the same hash — so you can compare fingerprints instead of the originals.
- Avalanche effect. Change a single character and the entire hash changes unrecognizably.
Crucially, a hash is not encryption: there is no key and no way to “decrypt” it. It's a fingerprint, not a locked box.
SHA-256, the Fingerprint
SHA-256, part of the SHA-2 family, produces a 256-bit digest. It is useful for fingerprints and integrity checks when the expected digest comes from a trusted source. A bare hash does not prove who created a file: someone who can replace both the file and its digest can make them match. Authentication needs a keyed construction such as HMAC, an authenticated-encryption tag, or a digital signature.
Passwords, Salt & OPAQUE
A conventional password-hash login stores a salted verifier rather than the plaintext password. At login, it processes the supplied secret again and compares the result. Two problems shape that design:
- Unsalted passwords share a hash. Without distinct salts, two users who both pick “password123” have matching stored hashes — and attackers can precompute giant tables (“rainbow tables”) of common passwords. The fix is a salt: a unique random value mixed in before hashing, so an attacker must do work for each salt instead of reusing one precomputed table across accounts.
- Fast hashes are too fast. A general-purpose hash like SHA-256 is built for speed, which lets an attacker try billions of guesses per second. Password hashing should be deliberately slow.
bcrypt combines a salt with an adjustable computational cost. Argon2id also makes memory consumption part of the cost. Both make guessing more expensive; neither removes the need for a strong password. A password-hashing function alone does not keep a password hidden from the server receiving it. OPAQUE changes the login protocol so the device can authenticate without sending the password.
A salt is public; a password is secret
Use a fresh, sufficiently long random salt for each password-hash record. Store it with the result: secrecy is not its job. Its job is to separate records and prevent reusable precomputation. It does not stop an attacker from guessing a weak password one candidate at a time.
Turning Secrets Into Keys
Encryption needs uniform, full-length keys, but the secrets we start with — a password, or the raw output of a key exchange — usually aren't in that shape. A key derivation function (KDF) bridges the gap. These functions have different jobs:
- Argon2id — a memory-hard function that makes each guess consume memory as well as computation. OWL’s OPAQUE suite applies it to the OPRF-derived result, using 64 MiB of memory, three passes and one lane. See RFC 9106 for Argon2’s design.
- PBKDF2 (Password-Based Key Derivation Function 2) — repeats a keyed hash to increase derivation cost. OWL uses PBKDF2-HMAC-SHA256 in its separate user-held recovery-key envelopes. A KDF can also process a strong random recovery secret; it is not limited to human passwords.
- HKDF (HMAC-based KDF) — for deriving keys from a high-entropy secret that's already strong but not uniformly shaped, such as the shared secret produced by an ECDH key agreement. HKDF “extracts and expands” that secret into one or more clean keys. It separates keys by purpose, but does not add password-guessing resistance. It should not replace a password-stretching function.
How NDEVR Uses Them
OWL combines these tools for separate purposes. Its OPAQUE sign-in uses an oblivious pseudorandom function and Argon2id, and returns a client-only export key. In OWL’s OWPK v2 format, HKDF-SHA256 derives an AES-256-GCM wrapping key from that export key to protect the account’s private key. The server stores the encrypted envelope; the device opens it. HKDF also derives the wrapping keys used by ECIES, while the user-held recovery key protects a separate recovery envelope. Password authentication, account-key protection and file encryption each have a distinct role.
References & Further Reading
- NIST, FIPS 180-4: Secure Hash Standard — defines SHA-256.
- NIST, SP 800-132 and IETF RFC 8018 — PBKDF2.
- IETF, RFC 5869: HKDF — HMAC-based key derivation.
- Provos & Mazières, A Future-Adaptable Password Scheme (1999) — the bcrypt paper.
- IRTF, RFC 9106: Argon2 and RFC 9807: OPAQUE — memory-hard password processing and password-authenticated key exchange.