Store only a derived hash, never the plaintext password. Use a key derivation function such as Argon2, PBKDF2, bcrypt, or scrypt with a unique CSPRNG salt per password and a tuned work factor. The goal is to make each guess expensive enough that stolen hashes are impractical to brute force with modern hardware.
Why This Matters for Security Teams
Password storage is one of the few controls that still has to withstand post-breach, offline attack conditions. Once a database is copied, defenders lose rate limits, lockouts, and most monitoring leverage, so the stored verifier itself becomes the last line of protection. That is why the right design stores only a one-way derived value, not the plaintext, and why the derivation function and work factor matter as much as the application logic around it.
The practical objective is to shift the economics of compromise. A unique salt prevents identical passwords from collapsing into the same hash, while a memory- and CPU-intensive derivation function makes each guess expensive enough to reduce the attacker’s throughput. In real incidents, weak hashing usually fails twice, first by enabling rapid guessing, and then by exposing every reused password across other services. Teams that treat password storage as a checkbox often discover that the real issue is not whether a hash exists, but whether it was built to survive modern cracking hardware.
In practice, many security teams discover weak password storage only after a database dump has already been monetised.
How It Works in Practice
The storage model should be simple: accept the password at signup or reset, derive a verifier with a dedicated password hashing function, then discard the original secret. Verification repeats the derivation on the login attempt and compares the results. The stored value should contain the algorithm parameters needed for verification, because those parameters are part of the record’s long-term usability.
For modern deployments, Argon2 is often the preferred choice because it can be tuned for memory hardness as well as compute cost. bcrypt, PBKDF2, and scrypt remain acceptable when implemented correctly, but they should still be configured so that cracking a single password is materially slow at your expected attacker scale. The key point is not which algorithm sounds strongest in the abstract, but whether the chosen settings force the attacker to spend meaningful time per guess.
- Use a unique, cryptographically secure salt for every password so identical passwords do not produce identical stored values.
- Store the algorithm identifier and tuning parameters with the hash so verification remains possible after future upgrades.
- Choose work factors based on current hardware reality, then revisit them as CPU and GPU performance improves.
- Reject plaintext storage, reversible encryption, and custom hashing schemes that were not built specifically for password verification.
- Protect any additional secret material, such as a server-side pepper, with separate operational controls and rotation planning.
This guidance tends to break down when teams force password verification into a legacy authentication stack that cannot support per-record parameter tuning or timely rehashing after compromise.
Common Variations and Edge Cases
Tighter password hashing settings usually increase login latency and infrastructure cost, so teams have to balance attacker resistance against user experience and authentication capacity. Best practice is evolving around memory-hard functions because raw GPU resistance is now a practical requirement, not an academic preference, but older systems may still need transitional settings while they are upgraded.
A few edge cases change the implementation choice. If a system uses a high-value credential store or expects large-scale offline exposure, memory hardness should be prioritised over simple iteration count. If the application must support very old platforms, PBKDF2 or bcrypt may be the least-bad interoperable option, but they still need a carefully chosen work factor and a plan for gradual replacement. If passwords are only one factor in a broader authentication flow, weak storage is still unacceptable because compromise of the verifier can expose reuse risk across unrelated accounts.
Operationally, the biggest mistake is treating hashing as a static control. Once cracking economics shift, yesterday’s safe parameters become tomorrow’s weak point. The storage design should therefore anticipate periodic rehashing, not just initial deployment.
Risk and Threat Considerations
The main risk is offline cracking after a database compromise, where the attacker can test guesses at scale without interacting with the live system. That removes lockouts, MFA prompts, and rate limits from the defender’s toolbox, so the stored password verifier must carry the burden of slowing brute force and dictionary attacks.
Failure mechanism: Weak or unsalted hashing enables rapid reuse of common-password lists, rainbow-table style optimisation, and high-throughput GPU cracking. Reversible storage is worse, because compromise immediately exposes the original password rather than just the verifier.
Impact: Attackers can recover credentials, reuse them across other services, and escalate from a single database exposure into account takeover, lateral compromise, and broader credential stuffing campaigns.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
CIS Controls v8 provides the primary governance reference for this topic.
| Framework | Control / Reference | Relevance |
|---|---|---|
| CIS Controls v8 | 6 — Access Control Management | Password storage protects credentials that grant access to systems and data. |
| 8 — Audit Log Management | Cracking-resistant storage reduces the blast radius of credential theft after compromise. | |
| Recommendation — Enforce secure credential storage and remove weak password handling from production systems. Protect password verifiers so stolen databases do not become easy credential sources. | ||
Practitioner Guidance
What to prioritise: Treat password storage as a cracking-resistance problem, not a data-formatting problem. The first question is whether the stored verifier can survive modern offline guessing at your assumed attacker budget.
Decision rule: If the application can store the password in plaintext or a reversible form, the design is wrong; if it can only store a hash, the next decision is whether the algorithm and work factor are strong enough to stay expensive over time.
What to measure: Track hash-verification latency, authentication throughput under peak load, and the time required to rehash accounts when parameters change. A secure setting is one that is still operationally tolerable while being materially costly to crack at scale.
Common mistake: Teams often pick an algorithm once and never revisit the cost factor. That creates a silent drift where the security control looks present but no longer meaningfully resists current hardware.
Practitioner takeaway: The right password storage design is the one that remains expensive for attackers even after the database is gone, because that is the moment when all of the other controls have already failed.
Related resources from NHI Mgmt Group
- How should security teams reduce the risk of cloud privilege abuse after a supply chain compromise?
- How should security teams handle rotated NHI credentials after a platform compromise?
- How should security teams manage token revocation after a platform compromise?
- How should security teams handle risky OneDrive files after they are identified?
Deepen Your Knowledge
Reviewed and updated by the NHIMG editorial team on September 15, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org