Linux Password Hashing Explained: /etc/shadow, Salting, and Security.
Learn how Linux password hashing works, how salts protect stored credentials, what /etc/shadow contains, and why modern systems use specialized password-hashing algorithms.
In our previous post, [Cryptographic Hashing Explained: Linux Commands and Examples], we explored cryptographic hashes and how Linux uses them to verify file integrity.
In this article, we'll focus on Linux password hashing and security. You'll learn how Linux stores password information in /etc/shadow, how salting protects credentials, and why specialized algorithms such as Argon2id, bcrypt, and yescrypt help defend against password-guessing attacks.
Understanding these mechanisms is essential for Linux administrators who want to secure user accounts and protect authentication credentials.
How Password Hashing Works
Password hashing transforms a password into a representation that can be stored and checked during authentication.
Consider a user who enters a password when logging in to a Linux system.
The authentication process typically works as follows:
- The user enters a password.
- The system retrieves the user's stored password-hash information.
- A password-verification function processes the supplied password using the stored parameters and salt.
- The system compares the result with the stored verifier.
- Authentication succeeds if verification passes and any other required authentication checks are satisfied.
The original password does not need to be stored in readable form.
Unlike encryption, password hashing is not designed to be reversed. When a user forgets a password, a properly configured system generally resets it rather than decrypting the original value.
Important: A password hash is not the same as a password. It is a stored representation used to verify a password attempt.
Where Linux Stores Password Information
On most traditional Linux systems, account information is maintained in two important files: /etc/passwd and /etc/shadow.
The /etc/passwd File
The /etc/passwd file contains basic account information, including usernames, user IDs, group IDs, home directories, and login shells.
You can inspect its contents with:
$ cat /etc/passwdA typical entry looks like this:
john:x:1000:1000:John Doe:/home/john:/bin/bashThe second field contains x, indicating that the password information is stored separately, usually in /etc/shadow.
The /etc/passwd file is generally readable by local users because many system components need to look up account information.
The /etc/shadow File
The /etc/shadow file contains password-hash information and related account-aging fields.
Because this information is security-sensitive, access is restricted to privileged users and authorized system components.
To inspect a specific account's entry, use:
$ sudo grep '^john:' /etc/shadowReplace john with the actual username.
A password-hash field may look like this:
$6$salt-value$hashed-password-valueThis is an illustrative example of the format used by SHA-512-based Unix password hashing.
A real entry contains the actual salt and encoded hash, along with account information in subsequent colon-separated fields.
Never share the contents of /etc/shadow publicly.
The stored hashes are not plaintext passwords, but an attacker who obtains them may attempt to recover the passwords through offline guessing.
Understanding Linux Password-Hash Formats
Linux password hashes often use a structured format that identifies the algorithm and its parameters.
For example:
$6$salt-value$hashed-password-valueThe components mean:
$6$identifies the SHA-512-basedcryptpassword-hashing format.salt-valuerepresents the salt used during hashing.hashed-password-valuerepresents the resulting encoded password hash.
The $6$ identifier does not mean that Linux simply calculates one ordinary SHA-512 hash of the password. The SHA-512-based crypt scheme uses a specific password-hashing construction with its own processing rules.
Other common identifiers include:
$1$— MD5-basedcrypt, an obsolete choice for password storage.$5$— SHA-256-basedcrypt.$6$— SHA-512-basedcrypt.$2a$,$2b$, or$2y$— variants associated with bcrypt.$y$— yescrypt, used by some Linux distributions.
The exact formats available depend on the Linux distribution, authentication configuration, and installed libraries.
Seeing a hash prefix helps identify the format, but it does not, by itself, prove that an account is securely configured.
What Is a Salt in Password Hashing?
A salt is a value incorporated into the password-hashing process to make identical passwords produce different stored results.
Consider two users who choose the same password.
Without a salt, a deterministic hashing process using the same algorithm and parameters produces the same hash for both users. An attacker who obtains the password database can immediately identify identical hash values.
With unique salts, the password-hashing function processes each password with a different salt. As a result, identical passwords generally produce different stored hashes.
Salts provide several important security benefits:
- They prevent identical passwords from automatically producing identical stored hashes when different salts are used.
- They make precomputed lookup tables, including conventional rainbow tables, far less useful against the salted hashes.
- They require attackers to perform separate password-guessing work for each salt rather than reusing one computed result across every account.
A salt does not need to be secret. It is normally stored alongside the password hash so that the system can verify future login attempts.
A salt does not make a weak password strong. Attackers can still guess common passwords and calculate the corresponding salted hash. Salting improves resistance to certain attacks, but it does not eliminate password guessing.
Why SHA-512 Alone Is Not Enough for Password Storage
SHA-512 is a cryptographic hash function that produces a 512-bit digest. It is useful for many integrity-related tasks, but its speed creates a problem when storing passwords.
General-purpose hash functions are designed to process data efficiently. Modern hardware can calculate enormous numbers of these hashes, allowing attackers to test many password guesses quickly if they obtain a password database.
For example, suppose an attacker obtains a database containing password hashes. The attacker can try candidate passwords, process each guess using the appropriate algorithm and parameters, and compare the results with the stolen entries.
If the password is weak and the hashing process is fast, the attacker may recover it relatively quickly.
This is why secure password storage requires more than selecting a cryptographically strong general-purpose hash function.
Password-hashing algorithms are deliberately designed to make each password guess more expensive.
Modern Password-Hashing Algorithms
Several algorithms are designed specifically for password storage. They use configurable parameters to increase the cost of testing password guesses.
Argon2id
Argon2id is a modern password-hashing algorithm that combines data-independent and data-dependent memory access patterns.
It is designed to make password guessing more expensive by using configurable memory, computation time, and parallelism.
Its memory requirements are particularly important because they can make large-scale attacks using specialized hardware more costly.
Argon2id is a strong choice for new applications when it is supported by the application framework and authentication infrastructure.
bcrypt
bcrypt is a widely deployed password-hashing algorithm based on the Blowfish cipher.
It includes a configurable work factor that controls the computational cost of hashing a password. Increasing the work factor makes each password guess more expensive.
bcrypt remains common in web applications and other authentication systems.
However, bcrypt has input-length limitations that developers must account for when implementing password storage. It should be used through a reputable library rather than implemented manually.
scrypt
scrypt is designed to make password guessing expensive in both computation and memory.
Its memory-hard design raises the cost of attacks that rely on testing huge numbers of password guesses in parallel.
It remains a relevant option for systems that support it.
PBKDF2
PBKDF2 derives a key from a password using a pseudorandom function and a configurable number of iterations.
Increasing the iteration count increases the work required for each password guess.
PBKDF2 is widely supported and appears in many established security standards and authentication systems. Its security depends on appropriate parameters and a suitable underlying pseudorandom function.
Which Algorithm Should You Choose?
For new applications, Argon2id is often a strong default when the platform supports it and the parameters can be tuned appropriately.
bcrypt, scrypt, and PBKDF2 can also be suitable choices depending on the application, platform requirements, and security policies.
The algorithm alone does not determine security. Developers and administrators must also consider:
- The strength of user-selected passwords.
- The algorithm's parameters and computational cost.
- The implementation and its handling of salts.
- The ability to upgrade parameters as hardware becomes faster.
- The authentication system's protection against online login attempts.
Use well-maintained authentication libraries and established system mechanisms rather than writing custom password-hashing code.
Common Password-Guessing Attacks
Understanding the threats against password hashes helps explain why modern password-storage methods matter.
Dictionary Attacks
A dictionary attack tests likely passwords from a list of common choices, leaked credentials, and predictable variations.
For example, an attacker may try passwords based on common words, names, dates, or familiar patterns.
Weak passwords are particularly vulnerable because they are likely to appear among the attacker's candidates.
Brute-Force Attacks
A brute-force attack systematically tests possible password combinations.
The cost depends on several factors, including password length, character variety, the algorithm's parameters, and the attacker's available computing resources.
Long, unique passwords generally provide greater resistance to guessing than short or predictable ones.
Rainbow-Table Attacks
Rainbow tables are precomputed structures used to speed up certain password-recovery operations.
Unique salts substantially reduce their usefulness because the attacker cannot directly reuse a single precomputed table across passwords with different salts.
However, salts do not prevent an attacker from generating new guesses and calculating the appropriate password hash for each candidate.
Offline Attacks
An offline attack occurs when an attacker obtains stored password hashes and tests guesses without needing to interact with the original login service.
This is particularly dangerous because the attacker may avoid online rate limits and account lockout mechanisms.
Using a suitable password-hashing algorithm, unique salts, strong passwords, and appropriate authentication controls helps reduce the risk.
Linux Password-Hashing Best Practices
When administering Linux systems, follow these practices to protect password credentials.
Use strong, unique passwords.
Avoid common words, predictable patterns, and password reuse across services.
Use modern password-hashing methods.
Where you control the application, prefer a well-maintained implementation of Argon2id or another appropriate password-hashing algorithm. For system accounts, follow the mechanisms supported by your Linux distribution.
Protect /etc/shadow.
Preserve its intended ownership and permissions. Do not make the file world-readable or copy it to unsecured locations.
Avoid exposing password hashes.
Treat password databases as sensitive authentication material even though they do not contain plaintext passwords.
Keep systems and authentication components updated.
Security fixes and improvements to password-handling implementations can reduce exposure to known weaknesses.
Use multifactor authentication where appropriate.
Additional authentication factors can help protect accounts even when a password is compromised.
Limit online login attempts.
Rate limiting, monitoring, and appropriate authentication policies can help reduce online guessing attacks. Remember that these controls do not, by themselves, stop offline attacks against stolen hashes.
Plan for algorithm upgrades.
Password-hashing parameters that were sufficiently expensive in the past may become inadequate as hardware improves. Use systems that support updating password hashes when users authenticate or reset their passwords.
Password hashing lets Linux verify credentials without storing plain-text passwords. While /etc/passwd and /etc/shadow serve distinct roles, hash formats define how credentials are processed.
True security requires more than basic hashing: unique salts prevent precomputed attacks, and memory-hard algorithms like Argon2id, bcrypt, scrypt, and PBKDF2 make password guessing computationally expensive. For administrators, mastering these mechanisms is vital for securing accounts and auditing systems.
Thanks for reading, and stay tuned for more Linux, infrastructure, and cybersecurity tutorials from SNUBmonkey™.