26

I read somewhere that adding a salt at the beginning of a password before hashing it is a bad idea. Instead, the article claimed it is much more secure to insert it somewhere in the middle of the password.

I don't remember where I found this, and I cannot find any other articles saying the same thing. I also don't understand why this may increase security.

So, is it true? Or does it not matter from a security perspective? If the assertion is true, can somebody explain why? Is it valid only for weak hashes, like MD5/SHA1?

Andrei Botalov
  • 5,317
  • 10
  • 46
  • 73
Arseni Mourzenko
  • 4,674
  • 6
  • 22
  • 30
  • 4
    It doesn't matter because you shouldn't be implementing your own password hashing scheme. If you do, it's likely to have more security holes than just how you mix in the salt. –  Aug 08 '10 at 04:38
  • @hobbs: er, just whose hashing scheme are you using? – ladenedge Aug 17 '10 at 15:40
  • 1
    @ladenedge ones that have been thoroughly reviewed, like the one from the PKCS#5 standard, or Provos and Mazières' Eksblowfish-based scheme. –  Aug 17 '10 at 19:59

6 Answers6

22

What this article could have meant is that putting the salt somewhere in the middle of the password supposedly increases the chance of being cracked by a dictionary attack or by brute force, because the rules to actually compose the same hash could not be implemented in your password cracker of choice. In reality, this is probably complete nonsense.

How does this work?

If you take a program like John the Ripper, you feed it with your password file like so (not the exact syntax):

username:password:salt

Then you pass the format as a parameter that you think the hash is generated with. This can be:

md5(pass + salt)
md5(salt + pass)
md5(md5(pass) + md5(salt))
md5(pass + md5(salt))
md5(md5(...(salt + pass + salt)...))
...
and whatnot.

John the Ripper comes with a premade set of about 16 subformats you get to choose from.

Putting the salt somewhere in the password would probably look like that:

md5(password.substring(0,4) + salt + password.substring(4,end))

So, using a technique like this requires you to write a small plugin for John at first, before you can start cracking (which shouldn't be a problem at all).

In addition, you, as an attacker, might have a list of hashes + salts of unknown origin and have no knowledge about the way how a hash is composed. This is rarely the case. If you, as an attacker, manage to extract hashes and salts from a database, you probably either find a way to extract the password hashing algorithm of the website or you just create a new account with a known password, extract the hash and salt for it and brute force the algorithm that was used to compose the final hash (which can be more or less challenging).

All in all, it is almost completely arbitrary where you put the salt and whether or not you iterate the hashing algorithm ten thousand times or not. This does NOT provide a significant amount of security.

If you want security, you can do way better by using a better hashing algorithm or bcrypt or something else that is computationally expensive.

Malady
  • 109
  • 4
ckck
  • 336
  • 2
  • 2
  • 1
    +1. I think this is a good candidate for a canonical answer. As for *"you probalby either find a way to extract the password hashing algorithm of the website"*, well, most attacks are based on SQL Injection, which doesn't give access to the hashing algorithm details. – Arseni Mourzenko Feb 15 '12 at 16:32
  • 3
    @MainMa: Have a look at [Kerckhoffs's principle](http://en.wikipedia.org/wiki/Kerckhoffs's_principle) - always assume that the attacker knows your algorithm. (At least, if you are going to publish advices about how to do this.) – Paŭlo Ebermann Feb 15 '12 at 20:57
  • 1
    @MainMa: Basically, you are right and there are certainly cases where you can't extract the hashing algorithm from the website. However, if a website is prone to SQL injection, in reality it often also has other flaws. Furthermore, you could use the SQL injection to extract parts of the file system via SELECT LOAD_FILE(), which on the other hand might require additional information about the file structure of the website. Or, you use the bruteforce approach I suggested. But thanks for clarification :) – ckck Feb 16 '12 at 08:47
  • 3
    Regarding the last two paragraphs of the answer: Iterating a hash algorithm ten thousand times makes it more computationally expensive. Iterating ten thousand times is equivalent to adding 13+ bits of entropy to the password, or conversely: Using a ten thousand times faster hash algorithm is equivalent to removing 13+ bits of entropy from the password. It's a matter of definition and context whether this is "significant", but there is no significant difference between iterating a fast algorithm or using one that is slow by itself. – Henrick Hellström Feb 17 '12 at 15:49
20

It depends on the hash function.

With a random oracle (which is the "ideal hash function"), there is no difference on how you put together salt and password at all, as long as both go in.

With real live hash functions there might be differences on the position of the input (like, there are extension attacks).

But then, you usually want to use some special password hashing scheme like PBKDF-2, bcrypt or scrypt, and these are already made with three inputs, one being the password and the other one the salt (the third one the work factor). Simply use them as they were meant to be used.

Paŭlo Ebermann
  • 2,477
  • 20
  • 20
  • 1
    Sometimes I think this site needs more people with crypto knowledge. Thank you for bringing up hash extension attacks. People, don't just hash passwords. PLEASE! Please use bcrypt2, scrypt or the like. – freddyb Feb 18 '12 at 21:47
  • 4
    @freddyb: A hash extension attack is not really a problem for password hashing, I think. All an attacker would get is to find another hash for a related (longer and with some strange null characters in the middle) password. The reason for bcrypt/scrypt/PBKDF is that fast hashing allows brute-forcing of small password spaces. – Paŭlo Ebermann Feb 18 '12 at 23:05
6

It is better to have randomness at the beginning of the input string, than at the end.

If the salt is a constant value for all passwords then it is easier to bruteforce multiple passwords if the salt is applied as:

hash(salt . password)

rather than

hash(password . salt)

The reason is simply because some (and I think both md5 and sha-1 fit this description) hashing algorithms are iterative - and if the string you are hashing starts with a known constant value it is possible to seed any cracking attempt with the result of hashing the salt, thus removing the benefits of salting your passwords.

If salt values are password specific (which they should be), the above does not apply, and the salt is likely to be more random than the password itself. For this reason, it's better to prepend the salt - though the difference/benefit is negligible.

The suggestion to insert the salt in the middle of the input string is likely another permutation of not starting the input string with a constant value - so long as you avoid that, the password is as secure as the hashing algorithm and the application using it.

AD7six
  • 238
  • 1
  • 3
  • 6
  • 3
    If the salt is a constant value for all passwords, then it isn't a salt. – Mark Jan 22 '18 at 23:05
  • There are two scenarios where you might want to use a salt. One is where you are salting a whole bunch of passwords on a server prior to their being hashed. In this case, you want each salt to be different. This works because you can store the salts on the server and reference each one by account. – Soren Stoutner Nov 16 '18 at 18:43
  • The second scenario is when you are salting a password that is being used to encrypt a file. In this scenario, the unencrypted random salt can be prepended to the ciphertext and transferred with the file. – Soren Stoutner Nov 16 '18 at 19:57
4

It would potentially be slightly more secure, but negligibly. I wouldn't worry about it and just prepend it for simplicity's sake. Almost every company I've worked for didn't even use a salt, so you are already more secure than most.

The chances of a hacker with a hash stolen from your database or a man-in-the-middle attack that has a salt applied is very unlikely to be found as opposed to un-salted hashes which can potentially be cracked easily with rainbow tables.

  • Of course. I am just curious about understanding why, in theory, is it more secure. –  Aug 08 '10 at 04:32
  • 4
    It is [very slightly] more secure because an attacker trying to brute force guess the salt would probably prepend it as that is the typical usage. –  Aug 08 '10 at 04:34
4

In other applications, when using an HMAC, both prepending and appending the secret key are vulnerable to different types of attack. Neither of these apply to salting a password hash, though, so either one should be satisfactory.

Nick Johnson
  • 201
  • 1
  • 4
-1

It is (even if only slightly) more secure based on the fact that if someone were to assume and test against salting they would definitely assume a prepended salt due to the frequency in which that occurs (and depending on how much they wanted access they may then try an appended salt)

Though it starts to become less of a time/memory tradeoff you most definitely can generate rainbow tables using salted passwords and they are still useful. Obviously, they take much longer to generate and take up much more space but even I have used them for some projects.

Were I implementing my own password hashing algorithm including salting I would pick somewhere that wasn't the very front or the very end for sure. I would also obviously not use a hard-coded salt due to the modicum of problems that would stem from that.

I can think of no reason why I wouldn't want to increase security (regardless of how negligible of an increase it may actually be) at the cost of little to no overhead increase.

AndrolGenhald
  • 15,506
  • 5
  • 45
  • 50
doyler
  • 602
  • 4
  • 11