# Do I need to use a CSPRNG when creating salts for user accounts?

I'm not sure about the need of using CSPRNG to create salts for each user account.

I found “Cryptographically Secure Pseudo-Random Number Generator in Qt/C++ (Cross platform)” (at StackOverflow) with some useful information, but I can't fully understand the reasoning behind it.

If an attacker have access to a copy of my users database table containing each salt and the related salted password, I can't understand how a CSPRNG would be more secure than a SHA12 hashed UUID. Can someone elaborate?

• Salts only need uniqueness, so a UUID is fine. A CSPRNG is just the simplest way to generate a salt, not the only one. – CodesInChaos May 25 '16 at 20:44
• I'm asking because I disagree it is the simplest. MySQL, for example, doesn't have a native CSPRNG. – incompleteness May 25 '16 at 20:52
• If you prefer a UUID that's perfectly fine, though I don't know why you'd want to implement password hashing on the database side instead of the application. In general I recommend using higher level APIs which take care of hashing and salting at the same time. e.g. php's password_hash/password_verify functions. – CodesInChaos May 25 '16 at 20:56
• There are several reasons. First, database servers are way more secure than web servers. They are, most of the time, only accessible through the application. Second, if your application is stolen, having the salt logic on it gives the attacker an edge. Third, I use salt in the database and pepper in the application, this way the attacker needs to stole both the application and the database. – incompleteness May 25 '16 at 21:26

If an attacker have access to a copy of my users database table containing each salt and the related salted password, I can't understand how a CSPRNG would be more secure than a SHA12 hashed UUID. Can someone elaborate?

I’m not sure if you only have read the question “Cryptographically Secure Pseudo-Random Number Generator in Qt/C++ (Cross platform)” at StackOverflow, or if you also noticed the accepted answer. The answer practically answers your question here, just like it answered the question at StackOverflow.

If you think you need a cryptographically secure PRNG for generating salts then I must tell you that you do not understand what the salt is and how and why it works and against which kinds of attacks it is useful.

The simple fact that the salt must be stored in plaintext alongside the hash of the salted password should have given away that you do not really need a cryptographically secure PRNG for salt - or any PRNG for that matter. Frankly, you could have a simple 64-bit number, which you increase by one every time you need a new salt and it would be just as secure as a salt generated by a cryptographically secure PRNG.

Even though that answer was posted back in 2012, things haven’t changed and it is still valid.

That is why CodesInChaos already commented correctly…

Quote:

Salts only need uniqueness, so a UUID is fine. A CSPRNG is just the simplest way to generate a salt, not the only one.

and Quote:

If you prefer a UUID that's perfectly fine, though I don't know why you'd want to implement password hashing on the database side instead of the application. In general I recommend using higher level APIs which take care of hashing and salting at the same time. e.g. php's password_hash/password_verify functions.

In the unlikely case you’re still unsure about salts and what exactly the reason for their existence is, I would like to point you to the question “Can you help me understand what a cryptographic “salt” is?“ and its accepted answer, which explains things using different wording. Quoting part of the accepted answer which seems to be the most relevant to your request for elaboration:

A salt is simply added to make a common password uncommon. A salt value is generated at random and can be fairly small, the only purpose is to lower the probability that the hash-value will be found in any pre-calculated table. A common way to combine the salt and the password is to simply concatenate them, i.e. the stored hash value is Hash(salt||password). The common password password1 now magically becomes, e.g., 6\$dK,3password1 and is very unlikely to be found in a table.

The salt can be stored completely in the clear in the database, next to the hashed value. Once the attacker has the database and wants to find the passwords, he needs to generate the pre-calculated table for each salt individually, a costly operation.

Besides that Q&A, you might want to search Crypto.SE for Q&As related to “salt” which might help you to fully grasp things related to salts. One of many examples: “Why not encrypt salt?

I'm asking because I disagree it is the simplest. MySQL, for example, doesn't have a native CSPRNG.

Then you could use a simple incrementing integer, or anything else that would produce a UNIQUE salt. (Please note the word “unique” has been capitalized as a hint, not to represent frowned-upon “online shouting”.)

There are several reasons. First, database servers are way more secure than web servers. They are, most of the time, only accessible through the application.

First off, I have to disagree with your database servers are way more secure than web servers because that is not really the case. But let’s assume that to be correct (as it is not relevant to your question anyway).

You have to remember that your salt only needs to be unique, not secret. It isn’t there as “a secret to secure data”. A salt is merely used to make things like passwords unique – slowing attackers down in situations where they might want to use things like hash-tables.

Second, if your application is stolen, having the salt logic on it gives the attacker an edge.

That argument isn’t really relevant in your scenario as the attacker would still have to “guess” the passwords – which are the real secrets (in contrast to the salts, better: the salting function within your application). That edge you see is rather minimal… and if you use a separate database server anyway, your attacker would be looking at a function within your application that can produce salts… but he/she would still have no copy of the database(s) to do anything useful with his/her ability to replicate the salts your application uses. For that, they would need to also steal the database.

Third, I use salt in the database and pepper in the application, this way the attacker needs to stole both the application and the database.

Great. Now all you need to do is to understand that a salt is not a secret. If an attacker knows the salt because – for example – he/she stole a copy of your database and can look it up quick and easy, that attacker would still need to brute-force the hashed passwords. Only when using a hash that is known to be cryptographically insecure, you would have given the attacker some kind of edge. But if you used something sane and cryptographically secure (like – for example – SHA256, HMAC256, or bcrypt), such an attacker will still be facing a loooong and painful brute-forcing attempt.