Password Hashing
PasswordHasher is the safe entry point for creating and verifying
password records.
It requires sensitive password input and normally requires an application key.
Storage Values and Verification
PasswordHash is an immutable, strictly parsed storage value.
PasswordVerification reports an explicit accepted or
rejected state and can carry a replacement record after a successful migration.
See Storing and Verifying Passwords for the complete workflow.
Policies and Keys
PasswordHashPolicy provides reviewed Argon2id and scrypt
presets.
PasswordHashKey holds the application pepper and can carry a
public identifier for rotation.
See Supported Password Hashing Algorithms for construction details, parameters, and migration
policy.
Interface
-
class PasswordHash
An immutable canonical password-hash record suitable for database or configuration storage.
The default value is an invalid sentinel and is safe to use for malformed records and unknown users.
See: Password Hashing
Public Functions
-
inline bool isValid() const noexcept
Test whether this value contains a valid parsed record.
-
bool isKeyed() const noexcept
Test whether the record uses an application key.
-
PasswordHashAlgorithm algorithm() const
Get the stored algorithm.
- Throws:
err::LogicError – If this is the invalid sentinel.
Public Static Functions
-
static PasswordHash fromString(const text::String &text) noexcept
Parse a strict canonical record, returning the invalid sentinel on any error.
- Parameters:
text – The storage record.
- Returns:
The parsed record, or the invalid sentinel.
-
static PasswordHash fromStringOrThrow(const text::String &text)
Parse a strict canonical record.
- Parameters:
text – The storage record.
- Throws:
err::ParseError – If the record is malformed, noncanonical, unsupported, or exceeds resource limits.
- Returns:
The parsed record.
-
inline bool isValid() const noexcept
-
class PasswordHashAlgorithm
A password hashing algorithm supported by
PasswordHasher.See: Password Hashing
Public Types
Public Functions
-
constexpr PasswordHashAlgorithm() noexcept = default
Create the default Argon2id algorithm.
Public Static Functions
-
static std::optional<PasswordHashAlgorithm> fromString(const text::String &text) noexcept
Parse an exact lowercase algorithm identifier.
- Parameters:
text – The identifier to parse.
- Returns:
The matching algorithm, or no value for unsupported text.
-
constexpr PasswordHashAlgorithm() noexcept = default
-
class PasswordHasher
The safe password hashing and verification API.
Normal construction requires an application key. Mark password strings as sensitive whenever practical.
See: Password Hashing
Public Functions
-
explicit PasswordHasher(PasswordHashKey key, PasswordHashPolicy policy = PasswordHashPolicy::recommended())
Create a keyed password hasher.
- Parameters:
key – The active application key.
policy – The password-hashing policy.
-
explicit PasswordHasher(unsafe::UnsafeNoPasswordHashKey acknowledgement, PasswordHashPolicy policy = PasswordHashPolicy::recommended())
Create an explicitly unkeyed password hasher.
- Parameters:
acknowledgement – The explicit acknowledgement of reduced protection.
policy – The password-hashing policy.
-
PasswordHash hash(const text::String &password) const
Hash a password with a fresh 16-byte salt from
application().secureRandom().Empty passwords are accepted. Inputs larger than 1 MiB are rejected.
- Parameters:
password – The UTF-8 password. Sensitive marking is recommended but not required.
- Throws:
err::ParameterError – If the password exceeds 1 MiB of UTF-8 data.
- Returns:
The canonical password-hash record.
-
PasswordVerification verify(const text::String &password, const PasswordHash &storedHash) const
Verify a password and report an optional replacement hash.
Malformed/invalid records and unavailable keys run a dummy current-policy derivation before rejection.
- Parameters:
password – The UTF-8 password. Sensitive marking is recommended but not required.
storedHash – The stored canonical password-hash record.
- Returns:
The explicit accepted or rejected result.
-
inline const PasswordHashPolicy &policy() const noexcept
Get the active password-hashing policy.
Public Static Functions
-
static auto withKeyRotation(PasswordHashKey activeKey, util::List<PasswordHashKey> fallbackKeys, PasswordHashPolicy policy = PasswordHashPolicy::recommended()) -> PasswordHasher
Create a keyed hasher with fallback keys for rotation.
The active key must be identified. Fallback identifiers must be unique; at most one fallback may be unnamed.
- Parameters:
activeKey – The identified key used for new records.
fallbackKeys – The legacy keys accepted during verification.
policy – The password-hashing policy.
- Throws:
err::ParameterError – If the rotation set is ambiguous.
- Returns:
The configured password hasher.
-
explicit PasswordHasher(PasswordHashKey key, PasswordHashPolicy policy = PasswordHashPolicy::recommended())
-
class PasswordHashKey
A system/application key used as a password-hash pepper.
Key material must contain at least 32 bytes. Keep it outside the password database, preferably in a secret manager or operating-system protected key store.
See: Password Hashing
Public Functions
-
explicit PasswordHashKey(mem::ByteBlock key)
Create the normal unnamed application key.
The key’s shared allocation is marked as sensitive by this constructor.
- Parameters:
key – The application-key material.
- Throws:
err::ParameterError – If the key contains fewer than 32 bytes.
-
inline bool isIdentified() const noexcept
Test whether this key has a public rotation identifier.
Public Static Functions
-
static PasswordHashKey identified(text::String identifier, mem::ByteBlock key)
Create an identified key for rotation.
Identifiers contain 1-32 characters from ASCII letters, digits,
.,_, and-.- Parameters:
identifier – The public rotation identifier.
key – The application-key material, marked as sensitive by the resulting key.
- Throws:
err::ParameterError – If the key or identifier is invalid.
- Returns:
The identified key.
-
explicit PasswordHashKey(mem::ByteBlock key)
-
class PasswordHashPolicy
A reviewed password-hashing policy.
Safe presets always use a 16-byte salt and a 32-byte raw output.
See: Password Hashing
Public Functions
-
PasswordHashPolicy() noexcept
Create the recommended Argon2id policy.
-
explicit PasswordHashPolicy(const unsafe::UnsafeCustomPasswordHashParameters ¶meters) noexcept
Create a checked custom policy through the explicitly unsafe parameter API.
- Parameters:
parameters – The checked algorithm-specific costs.
-
bool isEqualTo(const PasswordHashPolicy &other) const noexcept
Test whether all algorithm and cost parameters match another policy.
-
inline PasswordHashAlgorithm algorithm() const noexcept
Get the password-hashing algorithm.
-
inline unit::ByteLength saltLength() const noexcept
Get the salt length.
-
inline unit::ByteLength outputLength() const noexcept
Get the derived-output length.
-
inline uint32_t memoryKiB() const noexcept
Get the Argon2id memory cost in kibibytes.
-
inline uint32_t passes() const noexcept
Get the Argon2id pass count.
-
inline uint32_t lanes() const noexcept
Get the Argon2id lane count.
-
inline uint64_t scryptCost() const noexcept
Get the scrypt CPU/memory cost parameter.
-
inline uint32_t scryptBlockSize() const noexcept
Get the scrypt block-size parameter.
-
inline uint32_t scryptParallelization() const noexcept
Get the scrypt parallelization parameter.
Public Static Functions
-
static PasswordHashPolicy recommended() noexcept
Argon2id with 64 MiB, three passes, and four lanes.
-
static PasswordHashPolicy lowMemory() noexcept
Argon2id with 19 MiB, two passes, and one lane.
-
static PasswordHashPolicy scrypt() noexcept
scrypt with N=2^17, r=8, and p=1.
-
PasswordHashPolicy() noexcept
-
class PasswordVerification
The explicit result of password verification.
This type deliberately has no boolean conversion, so callers must name the accepted/rejected state. An accepted result can carry a replacement hash that must be persisted after a successful migration.
See: Password Hashing
Public Functions
-
inline bool isAccepted() const noexcept
Test whether the password was accepted.
-
inline bool isRejected() const noexcept
Test whether the password was rejected.
-
inline const std::optional<PasswordHash> &replacementHash() const noexcept
Get the replacement hash required after an accepted migration.
-
inline bool isAccepted() const noexcept
-
class UnsafeCustomPasswordHashParameters
Explicit access to custom password-hashing costs.
Prefer the reviewed
PasswordHashPolicypresets. Custom values are checked against hard safety limits, but can still be too cheap for a real deployment.See: Password Hashing
Public Static Functions
-
static UnsafeCustomPasswordHashParameters argon2id(uint32_t memoryKiB, uint32_t passes, uint32_t lanes)
Create checked custom Argon2id parameters.
- Parameters:
memoryKiB – The memory cost in kibibytes.
passes – The pass count.
lanes – The parallel lane count.
- Throws:
err::ParameterError – If a value is outside the implementation’s safety limits.
- Returns:
The validated custom parameters.
-
static UnsafeCustomPasswordHashParameters scrypt(uint64_t cost, uint32_t blockSize, uint32_t parallelization)
Create checked custom scrypt parameters.
- Parameters:
cost – The CPU/memory cost parameter, which must be a power of two.
blockSize – The block-size parameter.
parallelization – The parallelization parameter.
- Throws:
err::ParameterError – If a value is outside the implementation’s safety limits.
- Returns:
The validated custom parameters.
-
static UnsafeCustomPasswordHashParameters argon2id(uint32_t memoryKiB, uint32_t passes, uint32_t lanes)
-
class UnsafeNoPasswordHashKey
An explicit acknowledgement that password hashes will be stored without an application pepper.
See: Password Hashing
Public Static Functions
-
static inline constexpr UnsafeNoPasswordHashKey acknowledgeRisk() noexcept
Explicitly acknowledge the reduced protection.
-
static inline constexpr UnsafeNoPasswordHashKey acknowledgeRisk() noexcept