21

I have no cyber security knowledge whatsoever, and am trying to safely store passwords in a database. I understood I need to use salt, to avoid rainbow table attacks and to make sure two users with the same password will have different password hashes.

However, does the complexity of the salt matter? I was planning on simply using the user's id (an integer that's incremented each time a new account is created), but is it good enough, or should I generate a more complex salt?

5
  • 16
    No offence, but if you “have no cyber security knowledge whatsoever”, then I don’t want you anywhere near my passwords. There is a lot more to safely handling passwords than using a good salt to store them. I hope this is just for practice, not for a production system. (On the other hand, your second sentence indicates that you do have some cyber security knowledge.) – Brian Drake Nov 9 '20 at 13:35
  • 1
    This is mainly for practice! And yes maybe I have some cyber security knowledge, by which I mean I read a little bit about it on a couple websites – Oscar Sjöstedt Nov 9 '20 at 13:43
  • 1
    In that case, there’s probably no reason not to share. Consider posting relevant code here or to the code review SE to learn more. – Brian Drake Nov 9 '20 at 13:47
  • Maybe related to the topic crypto.stackexchange.com/questions/1776/… – O.Badr Nov 9 '20 at 21:42
  • @O.Badr How about an answer on this site? – Brian Drake Nov 10 '20 at 11:53
45

The important part

The fact that you are generating salts on your own is a red flag. The best way to do this, especially if you have little experience with security, is to use an established library for password hashing.

A well-designed library will generate and use salts automatically for you, and it will store the salt and the hash in the same string, that you put in one column in your database.

So, use a slow algorithm designed for password hashing, and use an established library, and you won't have to think about how to generate the salt.

The answer

Still, I should answer your question. Does it matter if the salt has high entropy? There are two properties that we may want the salt to have here, that randomness helps with:

  • Unique, in your database, between password changes and preferably globally, so that an attacker can only crack one password at a time.
  • Unknown to the attacker (before a breach), so that an attacker targeting a specific account can not start any preparatory work before the database is leaked.

Using a counter as salt is a decent solution, but not perfect. The salt is at least locally unique, but it's not globally unique or even unique over multiple installations of the same software. It's not unknown to the attacker, but that really isn't such a big issue. Once the hash is leaked, the salt will be leaked too.

But still, using a library that gives you a random salt will be better. Don't mess around with homebrew solutions for something as important as this!

8
  • Okay, I will do so, thank you! Still, I was interested in knowing how it works, even if I end up using a library in the final product. – Oscar Sjöstedt Nov 8 '20 at 14:58
  • 4
    @OscarSjöstedt As long as the salts are unique, you get almost all of the benefits. However, if an attacker is targeting a specific account, if the salt is known (e.g. its the user id) the attacker can start making rainbow table or computing hashes for that specific account even before the breach, giving them more time. I would not consider that a big issue, though. – Anders Nov 8 '20 at 16:04
  • @OscarSjöstedt I updated my answer to be more of an actual answer to your question. – Anders Nov 9 '20 at 8:28
  • 11
    Using a counter is even more problematic if you plan on running many instances of the same program, say if you are writing a CMS or a forum software. Likely the first few accounts will always be generated in the same order and include some sort of admin-account with additional powers. If you use a counter as salt, this means that all these admin accounts have the same salt, which makes calculating the one corresponding rainbow table much more valuable. – mlk Nov 9 '20 at 12:56
  • 1
    @Acccumulation The salt is not secret, but also not shown to the attacker at will. The reason why you don't want to show your salt is to prevent attackers from already pre-generating hashes without even cracking he database. But you don't take any special steps to "encrypt" the salt because that'd be useless anyways. – MechMK1 Nov 10 '20 at 10:45
1

Yes it does matter, Using a known salt or like you are using by incrementing id is not much secure. You should use a random salt. You some salt generator alog/libraries etc.

2
  • I will do as such, thank you! – Oscar Sjöstedt Nov 8 '20 at 14:59
  • This answer does not provide anything over the older answer by Anders – Falco Nov 10 '20 at 12:57
1

TL;DR: it's not good enough, instead let your salt be 10 bytes of /dev/urandom.

the salt does matter, and an user id is "not good enough" - it's much better than no salt at all, but to imagine a scenario where "uid as salt" is not good enough, imagine that multiple systems used salt is uid, and uid 0 is admin user (for example, on all linux systems, uid 0 is the admin account known as root), if Linux used uid as the salt for password hashes, i guarantee there would be rainbow tables out there for the 0-salt to attack root passwords, you'd probably even be able to google the hashes if that were the case, defeating the purpose of the salt :)

(another popular uid in Linux is uid 1000 or 1001, which is usually "the first user account", and the first user account is usually an account with sudo-access)

2
  • 1
    Why do you make this very specific recommendation: “10 bytes of /dev/urandom”? Why 10 bytes? What if the developer is using a high-level language where there is a better way of getting entropy? – Brian Drake Nov 10 '20 at 13:32
  • 1
    @BrianDrake well 10 bytes is way more than enough, but i don't know what the lower limit is (maybe even 4 bytes is good enough, i don't know, but i know that 10 more than enough), as for /dev/urandom, i meant the concept of /dev/urandom: cryptographically secure random bytes, regardless of the source (/dev/urandom is just a famous source - less famous sources include the linux api getrandom, the windows api CryptGenRandom, the openssl api RAND_bytes, etc) – user1067003 Nov 10 '20 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.