0

I've been doing some research about storing salts, and apparently the most common way to do it is to store it in a separate column in the same table as the username and password. I've seen that all over this and other websites, but to me this is like putting the key right next to the safe. If anyone ever gets access to the authentication table the hackers would win. If they do but the salt isn't found there they wouldn't have as much to go on.

I operate a three tiered system and would prefer some method of storing the salt somewhere on Java operated middle-tier that is behind a firewall and not accessible directly from the internet. Perhaps some XML or something that none of the other parts of the application will touch?

Marcel Marino
  • 962
  • 3
  • 17
  • 34
  • 1
    Salts can help protect against pre-computed hash attacks, and map two same passwords to completely different hashes. But it's not something you have to have another layer of security for. See https://security.stackexchange.com/questions/17421/how-to-store-salt – Andrew Li Feb 04 '18 at 17:43
  • 1
    Specifically: *"Now, since the goal of the salt is only to prevent pre-generated databases from being created, it doesn't need to be encrypted or obscured in the database. You can store it in plaintext. The goal is to force the attacker to have to crack the hashes once he gets the database, instead of being able to just look them all up in a rainbow table."* – Andrew Li Feb 04 '18 at 17:52
  • I'm confused what you mean about it preventing pre-generated databases? My understanding was that the salt was a way to prevent a hacker from reverse engineering the hash, but if they get the table that has both salt and password it would be almost as bad as if you never salted in the first place, no? – Marcel Marino Feb 04 '18 at 17:59
  • But the password is hashed before being put in the database right? If you did get into the database and get the salt as plaintext and a hashed password, there is still no good way to get the original password. Salts are used to prevent someone from building up a dictionary of common passwords and their hashes then checking it against your database. When there's a salt involved, that dictionary of common hashed passwords is now useless because now you have to take into account the salt. It's just infeasible to create a dictionary for every single salt. – Andrew Li Feb 04 '18 at 18:07

1 Answers1

2

Let's go over what the salt really is, then. It's a way of making sure

  • Two users with the password aren't obvious.
    • "password" with PBKDF2-HMAC-SHA-512, 10000 iterations, keeping only the first 32 bytes of output, stored in Base64, and a salt of empty string is ALWAYS

      9MpQfAfQvTG8d5oIdWgmpv2d2X1DrCXkspoJM6vqA/M=

    • Thus, if you have 5% of your users with that as their password hash, you can be pretty sure it's either "password" or "12345" or one of the other worst passwords.
  • Attackers cannot precompute attack lists in advance of leaks and then nearly-instantly match their "rainbow table" of results to the leak to eliminate that entire precomputed list, then get on with cracking the hard passwords without wasting precious time on the easy ones.

    • So, if we have an attacker with a password list of "password" and "12345", and you use no salt, they have already figured out that those results with the setup above are:

      9MpQfAfQvTG8d5oIdWgmpv2d2X1DrCXkspoJM6vqA/M=

    • and

      I2bEyBbaxTBvHdJ7rIu7kdR2liwGMCg62lyuoj41NB8=

    • Thus, the attacker gets your password list however, and they nearly instantly eliminate spending any computation time on the MANY of your users chose terrible passwords, which means they have more time, and combinations, left to try on the higher difficulty targets.

  • If you use a 16 byte cryptographically random salt for each userid, then instead of needing to perform the hash algorithm once for each password*rule on their list, they have to perform it 2^128 times for each, which is computationally infeasable at this time, let alone the storage requirements.

There's no point in keeping the salt secret - it serves those two purposes without any need for more secrecy than the password hash itself.

Anti-weakpasswords
  • 2,604
  • 20
  • 25
  • One more thing: The most common way to store salts is storing it as part of the hash-string, since a lot of password-hash implementations will pack them together in a format like [this](https://stackoverflow.com/a/20399775/575765). So there is really no advantage in storing them separately. – martinstoeckli Feb 05 '18 at 10:36
  • "Most" is debatable depending on your industry and toolset and the universe you're doing statistical analysis on... but common, absolutely - it's part of the string in many cases (PHP passlib), and it's just another column in the same record in many others (Microsoft .NET framework). – Anti-weakpasswords Feb 07 '18 at 03:53