Imagine that I am hashing the users' passwords with a random, long enough, salt, using key stretching, and a secure hash. Would it be more secure to finally encrypt the hash with a symmetric key?
-
1possible duplicate of [Password Hashing add salt + pepper or is salt enough?](http://security.stackexchange.com/questions/3272/password-hashing-add-salt-pepper-or-is-salt-enough) – Gilles 'SO- stop being evil' Nov 19 '13 at 14:00
6 Answers
What's the threat model? It could be of benefit to protect the password storage with an application-side secret, but only if you think it's a realistic scenario that your database is going to get compromised—without your application server, which holds the secret, also having been compromised.
Usually, the application layer is considered the more vulnerable part and the database layer more protected, and for this reason it is not considered useful to protect the data with an application-side secret. But that may not be the case for every app, and personally I would somewhat question this assumption given the prevalence of SQL injection.
The downside of introducing an app-side secret is that you now have to worry about key management processes. What's your mechanism for replacing the key if it gets compromised? Are you going to rotate it as a matter of course? How is your key stored so that you can move servers and not lose it (potentially making all your data useless)? For short-lived keys (used for eg signing session tokens) you may not care but for long-term password storage it becomes important.
The further downside with symmetric ciphers (especially block ciphers) is implementing them correctly. Since you are hashing and don't need recoverability, you could instead include the secret in the hash (as a ‘pepper’)... but then you wouldn't be able to re-hash all the password data on a key change, so you'd have to have a multi-key method for rollover.
ETA re comment @Pacerier:
Hashing does not prevent an offline guessing attack by someone who has obtained the password database. It only increases the amount of time it takes for that attack to bear fruit; with a hashing scheme of appropriate difficulty (ie rounds of key derivation rather than raw salt length per se), it will hopefully increase that amount of time to long enough for you to notice you've been hacked and change everyone's passwords before too many of their accounts are lost.
Protecting the content with a secret key (either using encryption or including the secret key in the hashed material) does prevent the offline guessing attack, but only as long as the secret key itself is not leaked. If the secret key is on the app server separate from the database server, the passwords are only attackable if both machines are compromised.
How much of a benefit that is arguable, given that many kinds of attack can end up compromising both, especially if the app server and database server are the same machine. There also is a price to pay in manageability as discussed. So whether there is net benefit needs to be judged on a case-by-case basis with reference to the threat model.
- 12,534
- 1
- 27
- 42
-
1The questions states that he is hashing with a random long enough salt. Then, what's the point of encrypting the hash in the first place? What's so vulnerable about just keeping the hash as plaintext? – Pacerier Nov 02 '14 at 20:29
I'm a big fan of adding layers of protection on top of a secure system as a part of a defense in depth policy. However, in this particular case, using symmetric encryption for this task creates another issue in the system; you'll have to take care of key management. The key must be stored somewhere, and if your application has access to it, then an attacker who compromised your system will very likely have access to the key.
Such procedure adds extra complexity to the system. Complexity is one of the enemies of security. I highly advise against it.
- 43,953
- 16
- 137
- 168
Encrypting the password-hashes can protect the passwords in a very specific situation.
There are scenarios when an attacker gains read access to your database, SQL-injection is one possibility, a leaking backup or a disposed server another. In this case, he can brute-force the password hashes. With an appropriate hash algorithm (key-derivation function), strong passwords will be safe, weak passwords though can be retrieved more or less fast with a dictionary attack (try the 1000 most used passwords...).
With encrypting your password hashes, you add a server side secret to your hashes. That means, additionally to the database, an attacker needs now privileges on the server (to get the key). This is the same advantage a pepper can give you, but it has the advantage, that you can exchange the key whenever this seems necessary.
Whether the key is stored safely is not that important, important are the additional privileges the attacker needs. In the worst case, the attacker will get the password hashes and you have the same situation as without encrytion.
- 5,189
- 2
- 27
- 32
-
"weak passwords though can be retrieved more or less fast with a dictionary attack " this statement is incorrect. It is wrong because OP says "I am hashing the users' passwords with a random, long enough, salt". Given salt is used dictionary attack becomes useless for a database. See http://stackoverflow.com/q/3566504/706456 for details. – oleksii Nov 12 '13 at 16:54
-
4@oleksii - Not really, the salt prevents using rainbow-tables and with unique salts, each password has to be brute-forced separately. Against brute-forcing a single password, a salt will not help. Today you can calculate several [Giga hashes per second](http://hashcat.net/oclhashcat-lite/#performance) with common hardware, that's why you need a slow algorithm. Even with a slow algorithm you can test for the most used passwords, this is kind of a dictionary attack. I would invite you to have a look at my tutorial about [secure password storing](http://www.martinstoeckli.ch/hash/en/index.php). – martinstoeckli Nov 12 '13 at 20:15
-
Another way to look at it: rate limiting and/or locking login attempts is widely agreed to be important for online attacks to prevent brute force and credential stuffing. It's a regular in the OWASP top 10. Offline attacks bypass these protections, as does SQL injection if it can use an endpoint not covered by the login rate limit or account locking. As well as compromising reused passwords on other sites, the attacker can potentially use the stuffed or brute forced credentials to login successfully to your site first time with no failed attempts. Well worth considering in your threat model. – drrob Apr 10 '20 at 10:11
I think there is a case for encrypting a secure digest.
It seems generally accepted that the best practice today is to use bcrypt, PBKDF2 or similar algorithms to salt and apply a work factor to the generation of the password digest. The use of a pepper is also an excellent way to mitigate poor or well known passwords from being easily brute-forced regardless of the algorithm/work factor being used.
However, the use of slow algorithms requires the work factor to be updated as hardware performance improves and it must be chosen to mitigate brute force attacks but not unduly slow password verification for users logging on to your system. By using symmetric encryption of a password hash both the work load and pepper requirements are no longer required. Provided the symmetric key is well protected (using an HSM for example) and good key management processes have been established I can't see a downside for this approach. The difficulty of a brute force attack is the same as brute forcing the key regardless of whether the password is of good quality or not.
I certainly wouldn't create the infrastructure to do this as all the previous comments regarding key management and keeping the key separate from the application server would apply. But if the infrastructure is already in place and well established there certainly are some upsides to encrypting a salted password hash.
- 11
- 1
I'd say no. For the reasons Adnan has said, the key needs to be accessible and this step is therefore probably just adding complexity to the system which is needless.
A better approach IMO would be to view the encryption as computing you could afford, but didn't use, and considering whether you could use that computing for a different hashing approach.
- 1,076
- 5
- 9
There is a misconception that layering different crypto practices results in something that is more secure than any individual practice on its own. However that's rarely the case.
Properly implemented password hashing with a long salt is cryptographically secure. The purpose of hashing and salting passwords is protecting the data at rest. Meaning no one that gets a hold of your password database should know what the passwords are and even if they do manage to crack one or more passwords that should not give any advantage to cracking another.
As Adobe has shown us in the past few weeks symmetric block ciphers are not great at this task. Hashing with salt avoids this problem completely.
Others have pointed out that further encrypting your hashed passwords introduces the problem of key management and offers no additional security/robustness for the stored data. Encryption is good for ensuring that only those with the proper credentials can access data. Encryption is reversible for this reason. This is not an authentication paradigm.
When we authenticate we want the server to use something that it knows (the salt) and a secret that only your user knows (the password) to consistently generate the same unique blob of data. We know that the user is who they say they are because we can reproduce this giant blob again and again. The salt ensures that even two identical passwords don't have the same hash in the database. Additional encryption offers no help on that front either.
- 539
- 3
- 5
-
21) Generally the salt is not a secret, since you can't assume that a compromised server manages to retain any secrets. Salted passwords are still vulnerable to password guessing attacks since humans suck as choosing good passwords. 2) It is possible to add a hopefully secret value to password hashes, either by encrypting the hash or by concatenating a secret value, commonly called pepper, to the salt. 3) Adobe has shown that adding a key can be useful since sometimes it doesn't get stolen/published. 4) Adobe hasn't shown why symmetric block ciphers are bad for this, only that ECB mode sucks. – CodesInChaos Nov 19 '13 at 16:23
-
5) There is no need for a password hash to be collision resistant. It only needs to be first pre-image resistant. – CodesInChaos Nov 19 '13 at 16:24
-
Edited above for clarity. Didn't mean to imply that the salt had to be secret, just that it's something the server has in its possession. Likewise, when mentioning collision resistance I was trying to illustrate that the salt is preventing two identical passwords from having the same hash in the database. – Matt Surabian Nov 19 '13 at 17:48
-
Five years later, not a single Adobe password has been hacked through cryptographic means. Only by comparing password hints, we can be reasonably sure of a few. The Adobe case is the *worst* example if you want to show that encrypting passwords is a bad idea since you're proving exactly the opposite. – Luc Oct 13 '18 at 11:56