Salt (cryptography)
![]() | hideThis article has multiple issues. Please help or discuss these issues on the talk page. (Learn how and when to remove these template messages)
|
In cryptography, a salt is random data that is used as an additional input to a one-way function that hashes data, a password or passphrase.[1] Salts are used to safeguard passwords in storage. Historically, only a cryptographic hash function of the password was stored on a system, but over time, additional safeguards were developed to protect against duplicate or common passwords being identifiable (as their hashes are identical).[2] Salting is one such protection.
A new salt is randomly generated for each password. Typically, the salt and the password (or its version after key stretching) are concatenated and fed to a cryptographic hash function, and the output hash value (but not the original password) is stored with the salt in a database. Hashing allows for later authentication without keeping and therefore risking exposure of the plaintext password if the authentication data store is compromised. Note that due to this, salts don't need to be encrypted or stored separately from the hashed password itself, because even if an attacker has access to the database with the hash values and the salts, the correct use of said salts will hinder common attacks.[1]
Salts defend against attacks that use precomputed tables (e.g. rainbow tables)[3] as they can make the size of table needed for a successful attack prohibitively large without burdening users. Since salts differ from one another, they also protect redundant (e.g. commonly-used, re-used) passwords as different salted hashes are created for different instances of the same password.
Cryptographic salts are broadly used in many modern computer systems, from Unix system credentials to Internet security.
Salts are closely related to the concept of a cryptographic nonce.
Example usage[]
Here is an incomplete example of a salt value for storing passwords. This first table has two username and password combinations. The password is not stored.
Username | Password |
---|---|
user1 | password123 |
user2 | password123 |
The salt value is generated at random and can be any length; in this case the salt value is 8 bytes long. The salt value is appended to the plaintext password and then the result is hashed, which is referred to as the hashed value. Both the salt value and hashed value are stored.
Username | Salt value | String to be hashed | Hashed value = SHA256 (Password + Salt value) |
---|---|---|---|
user1 | E1F53135E559C253 | password123E1F53135E559C253 | 72AE25495A7981C40622D49F9A52E4F1565C90F048F59027BD9C8C8900D5C3D8 |
user2 | 84B03D034B409D4E | password12384B03D034B409D4E | B4B6603ABC670967E99C7E7F1389E40CD16E78AD38EB1468EC2AA1E62B8BED3A |
As the table above illustrates, different salt values will create completely different hashed values, even when the plaintext passwords are exactly the same. Additionally, dictionary attacks are mitigated to a degree as an attacker cannot practically precompute the hashes. However, a salt cannot protect common or easily guessed passwords.
Common mistakes[]
Salt re-use[]
Using the same salt for all passwords is dangerous because a precomputed table which simply accounts for the salt will render the salt useless.
Generation of precomputed tables for databases with unique salts for every password is not viable because of the computational cost of doing so. But, if a common salt is used for all the entries, creating of such a table (that accounts for the salt) then becomes a viable and possibly successful attack.[4]
Because salt re-use can cause users with the same password to have the same hash, cracking a single hash can result in other passwords being compromised too.
Short salt[]
If a salt is too short, an attacker may precompute a table of every possible salt appended to every likely password. Using a long salt ensures such a table would be prohibitively large.[5]
Benefits[]
To understand the difference between cracking a single password and a set of them, consider a file with users and their hashed passwords. Say the file is unsalted. Then an attacker could pick a string, call it attempt[0], and then compute hash(attempt[0]). A user whose hash stored in the file is hash(attempt[0]) may or may not have password attempt[0]. However, even if attempt[0] is not the user's actual password, it will be accepted as if it were, because the system can only check passwords by computing the hash of the password entered and comparing it to the hash stored in the file. Thus, each match cracks a user password, and the chance of a match rises with the number of passwords in the file. In contrast, if salts are used, the attacker would have to compute hash(attempt[0] || salt[a]), compare against entry A, then hash(attempt[0] || salt[b]), compare against entry B, and so on. This prevents any one attempt from cracking multiple passwords (only when salt re-use is avoided).[6]
Salts also combat the use of precomputed tables for cracking passwords.[7] Such a table might simply map common passwords to their hashes, or it might do something more complex, like store the start and end points of a set of precomputed hash chains. In either case, salting can defend against the use of precomputed tables by lengthening hashes and having them draw from larger character sets, making it less likely that the table covers the resulting hashes. In particular, a precomputed table would need to cover the string [salt + hash] rather than simply [hash].
The modern shadow password system, in which password hashes and other security data are stored in a non-public file, somewhat mitigates these concerns. However, they remain relevant in multi-server installations which use centralized password management systems to push passwords or password hashes to multiple systems. In such installations, the root account on each individual system may be treated as less trusted than the administrators of the centralized password system, so it remains worthwhile to ensure that the security of the password hashing algorithm, including the generation of unique salt values, is adequate.[citation needed]
Another (lesser) benefit of a salt is as follows: two users might choose the same string as their password, or the same user might choose to use the same password on two machines. Without a salt, this password would be stored as the same hash string in the password file. This would disclose the fact that the two accounts have the same password, allowing anyone who knows one of the account's passwords to access the other account. By salting the passwords with two random characters, even if two accounts use the same password, no one can discover this just by reading hashes.
Unix implementations[]
1970s–1980s[]
Earlier versions of Unix used a password file /etc/passwd
to store the hashes of salted passwords (passwords prefixed with two-character random salts). In these older versions of Unix, the salt was also stored in the passwd file (as cleartext) together with the hash of the salted password. The password file was publicly readable for all users of the system. This was necessary so that user-privileged software tools could find user names and other information. The security of passwords is therefore protected only by the one-way functions (enciphering or hashing) used for the purpose. Early Unix implementations limited passwords to eight characters and used a 12-bit salt, which allowed for 4,096 possible salt values.[8] This was an appropriate balance for 1970s computational and storage costs.[9]
1980s–[]
The shadow password system is used to limit access to hashes and salt. The salt is eight characters, the hash is 86 characters, and the password length is unlimited.
Web-application implementations[]
It is common for a web application to store in a database the hash value of a user's password. Without a salt, a successful SQL injection attack may yield easily crackable passwords. Because many users re-use passwords for multiple sites, the use of a salt is an important component of overall web application security.[10] Some additional references for using a salt to secure password hashes in specific languages or libraries (PHP, the .NET libraries, etc.) can be found in the external links section below.
See also[]
- Password cracking
- Cryptographic nonce
- Initialization vector
- Padding
- "Spice" in the Hasty Pudding cipher
- Rainbow tables
- Pepper (cryptography)
References[]
- ^ Jump up to: a b "Download Limit Exceeded". citeseerx.ist.psu.edu. Retrieved 2021-05-14.
- ^ Anderson, Ross (2020). Security engineering : a guide to building dependable distributed systems (Third ed.). Indianapolis, Indiana. ISBN 978-1-119-64281-7. OCLC 1224516855.
- ^ Godwin, Anthony (10 September 2021). "Passwords Matter". Retrieved 2016-12-09.
- ^ "Secure Salted Password Hashing - How to do it Properly". crackstation.net. Retrieved 2021-03-19.
- ^ "Secure Salted Password Hashing - How to do it Properly".
- ^ "Password Storage - OWASP Cheat Sheet Series". cheatsheetseries.owasp.org. Retrieved 2021-03-19.
- ^ "How Rainbow Tables work". kestas.kuliukas.com.
- ^ Morris, Robert; Thompson, Ken (1978-04-03). "Password Security: A Case History". Murray Hill, NJ, USA: Bell Laboratories. Archived from the original on 2013-08-21. Cite journal requires
|journal=
(help) - ^ "How Unix Implements Passwords [Book]".
- ^ "ISC Diary – Hashing Passwords". Dshield.org. Retrieved 2011-10-15.
External links[]
- Wille, Christoph (2004-01-05). "Storing Passwords - done right!".
- OWASP Cryptographic Cheat Sheet
- how to encrypt user passwords
- Cryptography
- Password authentication