7

I have read many Q&As here on IT Security about password hashing and salting.

I am building a simple registration form for our community website which will be used by our members to create their accounts. I am seriously debating the idea of asking users a security question that will require a single word answer and then using the answer as a salt. Or maybe even answers with two or more words/numbers etc.

Of course, I will need to devise something with very little likelihood of repetition - say - the user's mother's maiden name. The likelihood of the exact same name in our 2000 strong community is extremely little. And the likelihood of a chosen password and the answer to the security question being identical is even more remote. However, such a question will necessarily have at least one space in the answer. Another idea is asking for the mother's date of birth and stripping the date separators.

Question 1: Is this a decent enough salting?

Question 2: Can a salt have a space? Or a slash? Or a hyphen?

Question 3: In case spaces (or slashes and hyphens) are not allowed in Salts, is it OK to perform some sort of a space (or slashes and hyphens)stripping on the input before the input is used as a salt?

Question 4: Are there any glaring security loop-holes this can open?

vinaya
  • 355
  • 3
  • 10
  • 5
    I think you may be confusing the [salt](http://security.stackexchange.com/questions/8015/what-should-be-used-as-a-salt) with an additional password or security question. There's no reason to ask a user for the salt when you can make up a far stronger salt with a good random number generator. If you expect the user to remember the answer to the question then it's not a salt, it's either an additional password or an additional security question. – Johnny Jul 23 '13 at 14:35
  • A couple of those who have replied/commented seem to have misunderstood my question! I need to ask the additional security question for an entirely different purpose. The reason for asking the question has no connection to creating a salt! The thought was just that since I (already) have a field that has hardly any chance of being duplicated, what would be the issues if I used that existing string for salting. – vinaya Jul 23 '13 at 16:07
  • 4
    Since the salt is stored along with the hashed password, using a security question as the salt makes the security question less secure. Even if you hash it, something like "mother's maiden name" or "street you grew up on" is a pretty small address space for a brute force attack, so anyone that steals your password database would likely be able to brute force many of the security questions. So there's no good reason to use a security question as salt, but there are reasons not to. – Johnny Jul 23 '13 at 18:11
  • Why would you ***not*** just use a random salt? – user253751 Jul 17 '16 at 11:00
  • @immibis - no reason really! When I asked the question about 3 years ago, I was just beginning in this field. The concept of Salt was really interesting and I was exploring different ways to implement it. The project got shelved right after I asked this question, but the learning I got from the responses here has helped me no end! So I completed the project (as a learning exercise) with randomly generated salts. – vinaya Jul 18 '16 at 07:17

5 Answers5

18

You want the salt to be unique. You also do not want the salt to be "revealing" because you will store it "as is", as clear text, on the database server. A salt needs not be secret, but people may get nervous if you store, unprotected, some value which they feel ought to be secret -- and this includes their mother's maiden name, which is apparently used by some US banks as an authentication mechanism.

Ensuring uniqueness of salts is easy on the server side: just generate a long enough sequence of random bytes. Randomness is not uniqueness, but it works just as well with overwhelming probability. Good password hashing functions can use any sequence of bytes as salt. Good implementations of password hashing functions will even generate the salt properly for you, and include it in their output, so you don't have to care about it (that's what normally occurs with bcrypt); in that case, forget all about this answer and your question, and just let the library do its job.

Asking the user to answer his own salt is a bad idea. First, it is technical, and most users can be assumed not to grasp anything about what a salt is; a lot of them will become nervous. Also, when users do understand what a salt is, then they know that a good salt is a random salt; human users are not well equipped at generating randomness (it is not part of what a human brain is good at). On the other hand, your server can do randomness. Finally, you cannot count on human users to enforce uniqueness -- and, in particular, when a user changes his password, he does not change his mother's maiden name, so that's an unavoidable failure at uniqueness.


Edit: if your programming language offers UUID, otherwise known as GUID (distinction is Byzantine), then these are good for salts. For instance, in .NET, just call System.Guid.NewGuid(). There are various methods for creating such values, but they all aim at worldwide uniqueness (they might be predictable, but that's not a problem for salts). "Method 4" is actually 122 bits of randomness. Best method for salt generation is to let the password hashing library code do it, but if you have to use a library which does not do it itself, then using a system-provided UUID is a decent low-effort method.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 1
    What banks use mother's maidens names as authentication - just so I can avoid them? – orlp Jul 23 '13 at 16:31
  • @orlp Every bank? It's a very common security question that is asked after you provide an SSN for example. – Navin Jul 19 '16 at 09:41
5

A salt is used to help prevent the use of rainbow tables and require an attacker to attack each hash separately. This only works if it is not feasible to make rainbow tables for the entire space of salts.

A user chosen salt is a) highly likely to not be unique, even locally and b) highly likely to be a value that might be found in a rainbow table database compared to a randomly chosen one. Both of these result in a great reduction in the effectiveness of the salt since they simplify attacks against the hash.

While the salt doesn't need to be random, it does need to be globally unique so that a DB of rainbow tables can't be used. Randomness is the easiest way to ensure this, though other viable options for deriving a salt do work.

There is no reason to use a user input, it is perfectly fine to simply use a random number and store it in the database with the user's record. This doesn't negatively impact security as the salt doesn't have to be unique, it just has to make use of pre-calculated rainbow tables infeasible.

AJ Henderson
  • 41,816
  • 5
  • 63
  • 110
4

As Terry said in his answer, the only requirement for a salt is to be unique for every password. Therefore I would just generate a random bytestring of at least 16 bytes long (make sure you use your operating system's random generator and not some wacky DIY implementation). Your Mother's maiden name may be something which is actually likely (there aren't so many different names, maybe only a thousand) to re-occur, it's more unlikely to generate the random bytes yourself.

Remember that you are allowed to store the salt plain text next to the password, a salt is not considered secret.

Lucas Kauffman
  • 54,169
  • 17
  • 112
  • 196
  • Hello Lucas, what exactly do you mean by "make sure you use your operating system's random generator and not some wacky DIY implementation"? (I am new to this and sometimes miss the most obvious of things!) – vinaya Jul 23 '13 at 12:38
  • 2
    A lot of people tend to implement their own random generators which are seemingly random but aren't considered cryptographically random. Note that for a salt, cryptographic randomness isn't required persé but honnestly it makes your life easier just to call a similar function os.random() which will just feed you some random bytes – Lucas Kauffman Jul 23 '13 at 12:41
  • Sorry if this sounds dumb - but what is os.random() - and where would I use it? In the php that processes the form? Or am I missing it completely? – vinaya Jul 23 '13 at 12:44
  • It was just a bit of pseudocode, it's just to generate your random salt. – Lucas Kauffman Jul 23 '13 at 12:48
  • 3
    Even the uniqueness requirement is rather soft. Occasional duplicates don't have a big effect on security, unlike most nonces. – CodesInChaos Jul 23 '13 at 13:48
  • 2
    @vinaya `mcrypt_create_iv(size, MCRYPT_DEV_URANDOM )` is the way to go in php – CodesInChaos Jul 23 '13 at 13:49
  • Thanks, @CodesInChaos! That bit of script goes a long way in helping me in my project. Unfortunately, though there are thousands of post/answers on this topic, there are few such concrete tips for beginners like me. Upvoted both comments. – vinaya Jul 24 '13 at 05:37
1

The only requirement of a salt is for it to be globally unique. If you are confident that you can achieve this requirement, by all means go ahead.

Think about it though, what exactly does your proposed scheme offer over the existing standard method of grabbing a few bytes of random data? Why do you want to piss your users of by asking for another input? Don't add more complexity for yourself and for your users. Stick with the standard method which is usually taken care of automatically by any decent password hashing library.

AJ Henderson
  • 41,816
  • 5
  • 63
  • 110
  • Thanks Terry! I agree that adding complexity doesn't make sense. Actually, this thought came to me because I was wondering about the Captcha and such to prevent auto submission of other forms on the website! I was thinking, if I need a captcha or some other method to prevent automated submission of forms, what if I used, instead, an input field where the user entered a piece of information he/she had supplied at the time of registration? – vinaya Jul 23 '13 at 12:29
  • Just clarified that it would need to be globally unique to avoid confusion with local uniqueness vs global. – AJ Henderson Jul 23 '13 at 13:38
  • 1
    Someone's name is unlikely to be *globally* unique. The salt needs to be globally unique, not just unique in one database at one point in time. – Gilles 'SO- stop being evil' Jul 23 '13 at 13:39
  • @vinaya Don't make the mistake of trying to use one field in your database for everything. If you want to use extra information as part of the login, *create a new field*, don't reuse cryptographic information. – Brendan Long Jul 23 '13 at 16:01
  • It is not clear that this is the "only requirement". Suppose that the salt is 32 bits wide, and you have 200 users. Is it acceptable if the password salts are the 32 bit values from 0 to 199? (I don't know; it may be true, but it's not obvious). – Kaz Jul 23 '13 at 20:35
  • @Kaz: Only if you can be reasonably sure that nobody else using the same password hashing method will use those same salts. Appending the name of your site/system to the salt would be one way to do that. (That said, there's also _some_ benefit to making salts not just unique but also unpredictable, since it prevents attackers from precomputing any useful hash tables _before_ they gain access to your user database.) – Ilmari Karonen Jul 23 '13 at 22:30
1

There is no reason not to make a salt random. You don't necessarily need cryptographically strong random numbers, just some bits from a PRNG that is seeded with a high resolution time of day and some other values like the process ID and whatnot.

Adding questions for additional profile info just for the purpose of creating a salt seems like a poor idea from a user experience and efficiency perspective.

If you're going to create the salt by hashing user profile info, use the values of properties which are already there. But, back to the first point: even if you use that info, there is no reason not to mix in additional variables unrelated to the user profile, like the microseconds portion of the time of day.

Re: The likelihood of the exact same name in our 2000 strong community is extremely little.

Ever heard of the birthday paradox? The odds that someone out of 2000 people has a particular surname are smaller than that there exist two people in a crowd of 2000 which have the same surname.

Kaz
  • 2,303
  • 16
  • 17
  • Though I agree that user input might not be a good idea for salts, the point about odds of duplicates is different. We in India have so many religions(>36,000 deities) and languages (>150 official), our zillion or so different names and surnames are written in a kazillion different ways (eg Adity, Aditya, Adithya - same name; my husband and I haven't met people with our first names in 50/54 years!) Birthday paradox is based on only 366 choices! And so far, we do not have a single duplicate combo of first name and last name in our community. Hence the idea! – vinaya Jul 24 '13 at 05:33
  • I see your point. So in India, "maiden name" is a full name, since both names change on marriage? Also, the birthday paradox is not literally about birthdays, with 366 values. This is just how the name is derived. The birthday paradox tells us, for instance, that it's more likely to find two files that has to the same hash code, than to find a file that hashes to a given hash. – Kaz Jul 24 '13 at 15:52