17

I'm learning about web security. I understand that passwords are hashed with salt. Why aren't the salts encrypted with same user's password? Cloudn't this make password cracking much harder?

Generating

  1. generate salt
  2. encrypt it with AES using user's password as key
  3. save the encrypted salt and hash

Retriving

  1. decrypt salt using supplied password
  2. hash salt + password
  3. compare to saved hash
1
  • 1
    Actually, there are some hash function constructions where hashing one block is basically using this block as a key to encrypt the previous hashing result. Commented Sep 5, 2014 at 20:27

3 Answers 3

38

generate salt encrypt it with AES using user's password as key save the encrypted salt and hash

You could do this and it would be an effective salt, however it wouldn't actually be any more secure than just using a regular salt.

Let's consider two attack vectors:

Password collisions

Obviously we don't want two users with the same password to have the same hashed password. To prevent this we use a random salt and assume that the probability of two users with the same password and the same randomly generated salt is effectively 0.

However, if two users happen to have the same password and coincidentally the same salt then they will have the same hash regardless of whether the salt is encrypted with their password or not encrypted at all. Therefore, by encrypting the salt you're not making it any less likely that a collision will occur in the salt. The only factors which do make it less likely is the quality of the random values used for the salt and the number of bits.

Brute force attacks

If an attacker is trying a brute force attack and you've encrypted the salt the only extra step they have to do is decrypt the stored salt each iteration and use that to produce the hash they then compared to the hashed password to see if they have a match.

This does require marginally more effort for an attacker, but when it comes to cryptography making something take only two or three times longer isn't significant. If brute forcing a password now takes 3 days instead of 2 you haven't really made it materially more secure. If you're trying to make something secure you want it to take 5000 years instead of 2 days.

If you want to slow down brute force attacks you'd be better off iterating your hashing process tens of thousands of times or using a hash function which is specifically designed to be computationally slow.

2
  • I don't disagree with this answer, but for the brute force part doesn't the point about an attacker having to decrypt the salt every time assume that they know that you've encrypted it? If they've only compromised the DB they wouldn't necessarily know that. Probably safest to assume the worst, though, and anything you do that in itself isn't cryptographically strong may as well be discounted.
    – frumious
    Commented Sep 5, 2014 at 20:25
  • 6
    @frumious I reject that whether a specific attacker knows it's encrypted is relevant to the answer. Firstly, any cryptosystem should be equally secure regardless of whether an attacker knows the internals. Secondly, database servers are rarely compromised directly, more often the application is compromised then the DB credentials extracted from that and the DB dumped using those credentials. Thirdly, even without encryption, how would an attacker know your salting scheme? You don't have to use encryption to obfuscate your salting scheme, but it shouldn't be necessary any way.
    – thexacre
    Commented Sep 5, 2014 at 22:49
21

Salts are not intended to be secret — their only requirement is to be globally unique.

Until you are more experienced, don't try to be clever with cryptography. Use out-of-the-box solutions like bcrypt or scrypt and leave the details to professionals. Cryptography is hard to get right, and adding more and/or unnecessary complexity only increases the likelihood of making a mistake and reducing security.

6
  • You don't need a salt to be truly globally unique, do you? Just for clashes to be unlikely enough that password/salt collisions (as in @thexacre's answer) are rare, and there's no point an attacker precomputing hashes. They usually are unique I expect, but there's no guarantee...
    – frumious
    Commented Sep 5, 2014 at 20:22
  • @Stephen Touset "Don't roll your own (cryptography)." Yes, that is the typical (good) advice, but one is bound to wonder if the existing out-of-the-box solutions can be trusted or haven't already been secretly cracked. If I roll my own derivative, it may not be perfect, but I'm likely not to go down with the rest of the world when a vulnerability for the out-of-the-box solution is discovered. And cryptography is fun to experiment with, so I say don't leave the details to the professionals.
    – AlfredBr
    Commented Sep 5, 2014 at 21:04
  • 9
    You are infinitely more likely to fall victim to bugs of your own doing. We have very high confidence in most cryptographic algorithms themselves — many have security proofs (e.g., RSA, HMAC), and others have simply stood the test of time against extensive cryptanalysis (e.g., AES). Cryptography is definitely fun to experiment with, and I would never discourage someone from doing so for fun and educational purposes. Systems that will handle other people's data, on the other hand, are not the place to experiment. Commented Sep 5, 2014 at 21:38
  • 1
    @frumious they should indeed be globally unique. Your aim is to prevent all possible methods of decrypting the passwords which are faster than brute forcing every single one from scratch, this includes rainbow tables. Imagine a scenario like facebook where they have 1.2b users, if hypothetically they only used a 16 bit salt then an attacker could calculate a rainbow table for any salt and compromise 18k accounts. In facebooks case they should use at least 31 bits for their salt (and probably considerably more) to ensure they're unique.
    – thexacre
    Commented Sep 5, 2014 at 22:58
  • 3
    The OP has quite explicitly said that he's learning web security and asking a theoretical question not implementing his own cryptographic suite so rehashing the same old answer - 'leave it to the professionals' isn't quite applicable here but I'll admit it's an easy way for upvotes so I'll give you that.
    – alex.p
    Commented Sep 6, 2014 at 11:08
0

As thexacre says, it doesn't impede brute force methods, because the guess can be used to decrypt the hash.

However, if there turns out to be (i.e. future discovery) a systematic vulnerability in the hash used, then an encrypted salt might prove valuable. Depending on the nature of the attack, though, it might be possible to derive both salt and password just as easily as deriving the password alone.

3
  • I'm dubious as to how true this is. Let's say you managed to produce a function which takes a hashed value and produces a set of possible inputs which would produce that hash. If I had a regular salt I'd iterate through that set to find a value where the known salt is a prefix. If you encrypted the salt you'd do the same thing except you'd iterate until you found a value where the prefix (ie. the salt) encrypted with the suffix (ie. the password) matched the known encrypted salt. I can't see how fundamentally the encryption would help. An example would make your answer much better ;)
    – thexacre
    Commented Sep 8, 2014 at 4:34
  • @thexacre: Perhaps the attack reduces the strength of the input by, say 12 bits, by making it possible to compute the last 12 bits from the others. This makes a brute force attack some 4096 times faster if the salt is known. If the salt is dependent on the password, the attack is defeated (one can't determine the salt without the last 12 bits, and can't determine those bits without the salt).
    – Ben Voigt
    Commented Sep 8, 2014 at 4:56
  • @thexacre: Does that sound like a valid scenario (an attack is discovered that can calculate the last 12 bits of the hash input without enumerating them all)?
    – Ben Voigt
    Commented Sep 8, 2014 at 16:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .