Back to blog

Password hashing in 2026


Own Auth stores new password verifiers with Argon2id and upgrades supported scrypt records after successful password verification. Routes pass the supplied password to Own Auth unchanged. They do not pre-hash, encrypt, truncate, or apply a second application digest before calling the package.

Use Argon2id for new password hashes

OWASP recommends Argon2id for new systems. RFC 9106 defines it as the primary Argon2 variant, combining resistance to side-channel attacks with protection against time-memory tradeoffs. Memory, iterations, parallelism, salt length, and output length are encoded with the verifier, so verification can reproduce the parameters used for an individual record.

OWASP's current minimum Argon2id profile uses 19 MiB of memory, two iterations, and one degree of parallelism. RFC 9106 also gives profiles for environments that can dedicate more resources. Own Auth does not expose an algorithm switch, which prevents application configuration from downgrading new credentials to a faster hash.

Argon2id verification consumes enough memory and CPU to become a capacity limit under concurrent sign-in traffic. Authentication rate limits and bounded verification concurrency must cover that path. The relevant measurement is latency and memory use at expected concurrency on production-like hardware, not the duration of one local hash.

Salts, peppers, and token secrets are different

Each encoded password verifier includes a unique salt and the Argon2id parameters used to derive it. The salt is stored with the hash and is not a secret. A password pepper would be a separate shared secret, but changing one requires the user's plaintext password or a forced reset for every affected verifier.

OWN_AUTH_TOKEN_PEPPER is not a password pepper. Own Auth uses it to protect hashes of session tokens, magic links, password-reset tokens, phone codes, invitations, and API keys. The public configuration does not describe it as an input to password hashing.

Keep password policy out of request schemas

Storage strength and password selection policy solve different problems. NIST SP 800-63B requires at least 15 characters for a password used as a single authentication factor, allows a minimum of eight when the password is part of multi-factor authentication, recommends accepting at least 64 characters, rejects arbitrary composition rules, and requires comparison against a blocklist of common or compromised values.

Own Auth exposes password.minLength and returns weak_password when a new value is shorter than the configured minimum. Configure that rule once in Own Auth. An HTTP schema should confirm that the field is a string and is present, not duplicate the minimum in every route. Duplicated policy drifts when the central setting changes and can produce inconsistent behavior between sign-up, reset, and password change.

Upgrade hashes during successful authentication

Hash formats should carry enough metadata to identify the algorithm and cost used for each record. After a successful verification, compare the stored parameters with the current policy and replace an outdated hash while the plaintext password is available in memory. OWASP describes this sign-in-time rehash as the common migration path.

Own Auth supports existing scrypt password hashes and upgrades them to Argon2id immediately after successful password verification, before a completed session or MFA challenge is returned. The old hash remains valid until the password is verified, which avoids a forced reset for active users. Accounts that never return cannot be rehashed without their password. A long-term migration plan can expire legacy verifiers and require recovery for dormant accounts after an announced deadline.

Check the stored verifier

A deployed check should create a credential, confirm that the stored verifier identifies Argon2id, sign in with a supported scrypt record, and confirm that Own Auth replaced it. Long and Unicode passwords should reach Own Auth without transport or validation truncation. Plaintext values must remain absent from logs, traces, analytics, queues, and error reports.