2

I'm using Rfc2898DeriveBytes in my application to encrypt a password with a randomly generated salt, and with a set iterator count for slowness.

Before, I just grabbed the generated salt and put it as a parameter for Rfc2898DeriveBytes to take care of, but now I've changed my approach to the following, and I'm wondering if it's doing more good, or more bad:

  1. Generate a random salt.
  2. Append the password to the salt.
  3. Hash the salt, using SHA-512.
  4. Pass the hashed salt to Rfc2898DeriveBytes, so it can do its magic.

I'm aware that any salt I provide to Rfc2898DeriveBytes, as long as it's unique/randomly generated, is considered a "true" salt, due to the nature of how the method operates. Does that mean that it'd be just as good as to pass the generated salt without any of the above modifications? (appending the password to it, and hashing it)

For informational purposes, the hashing algorithm Rfc2898DeriveBytes uses, is SHA512.

  • 1
    Do you mean "encrypt" or do you mean "hash"? You can't encrypt something with SHA-512. – MechMK1 Aug 26 at 14:34
  • @MechMK1 I meant hashing, sorry. I'll edit it now. – Support Monica - SpiritBob Aug 26 at 14:36
  • Why are you making it so complicated? Rfc2898DeriveBytes takes 3 arguments: A password, a salt and an iteration count. What stops you from providing exactly these three things as needed? – MechMK1 Aug 26 at 14:40
  • @MechMK1 That's what I'd like to know! Am I doing any good with these changes, or not? I've always just given the salt, without modifying it. On another note, the method for me takes 4 arguments -> password, the salt, iteration count, the algorithm used to generate the HMAC (In my case SHA512). – Support Monica - SpiritBob Aug 26 at 14:42
0

Nope, that's very much not a good idea. Just using the random salt from your step #1 is likely good enough. Section 4.1 of RFC 2898 provides recommendations for how to generate salts; the additional suggestion they make is that some applications will want to also have associated data pertaining to the encryption/decryption context.

The problem with using the password as an input to salt generation is that salts need to be independent of the password. Password crackers work off a base of knowledge about how users pick passwords, embodied in things like huge password dictionaries. The purpose of salts is to prevent attackers from using this knowledge to precompute any sort of table that allows them to speed up their cracking once they do manage to steal a password database. In the degenerate case where the password serves also as the salt, this goal is completely negated—the attacker can use their knowledge about common passwords to precompute each one's corresponding salt as well.

The fact that you incorporate both a random value (your step #1) and the password (step #2) in synthesizing your salts probably defeats such an attack, but the random salt from step #1 is already sufficient to do so; incorporating the password into salt generation is only playing with fire.

  • 1
    Thank you for the read. I think you've fully understood what I was asking, and shed some light as to whether my additional steps for salt generation improved the security as a whole, or are simply something unnecessary, which seems to be the case. Do you think peppering is good in cases like these? – Support Monica - SpiritBob Aug 27 at 7:56
4

Why is using the password as part of the salt a problem?

Because you need to store the salt separately from the hash of the password. You can either do this by encoding them in a specific way, such as storing them as $Rfc2898$iterations$mysalt$myhash or by using dedicated database tables.

If you would go with the scheme you proposed (crating a random salt, appending the password and hashing it with SHA-512), then an attacker would not need to crack the 100000 rounds of PBKDF2 at all. Why? Because you provided them with what is essentially SHA-512(password, salt). The fact that you later use this data as input for a more computationally expensive form of hash doesn't matter, because you need to save this data for further verification?

But what if I just save the random part of the salt and then mix the user input in on-the-fly?

Yes, you just proved that mixing in the password gives you no security gain whatsoever. All you need is the random part!

  • The salt argument for the method constructor I'm using, is of type byte[]. I believe I'm using the most extensible constructor for the class, and it's only specifications for the salt argument, is that it shouldn't be below 8 bytes (docs.microsoft.com/en-us/dotnet/api/…). Contrary to what you claim, I think providing a modified salt to the method isn't the main concern, or a problem. It's whether it does any good for us, which I hope you can shed some light on! – Support Monica - SpiritBob Aug 26 at 15:19
  • @SpiritBob If you provide the salt as saltSize, the application will generate a salt for you. This may be convenient if you create a hash for the first time, not for verifying it. – MechMK1 Aug 26 at 15:22
  • I'm aware. I've seen all the possible constructors that class has to offer. The question isn't about functionality. It's about possible improvement of security. – Support Monica - SpiritBob Aug 26 at 15:24
  • @SpiritBob I completely reworded my answer. I hope this sheds some light on it. The extremely short version is: In the best case, it's unnecessary. In the worst case, it's a huge security risk. – MechMK1 Aug 26 at 15:29
  • I'm confused by your new answer. If we avoid using Rfc, then the safest way to store passwords in our database would be by using Hash/Salt, where the Hash is (password + salt), and salt is just salt. In my case though, I don't see where the problem is. We compute a hash which again is formed by (password + salt), but the salt is formed by the following things: (SHA512(password + random stuff)). How is that a bad practice? Furthermore, the hash is also protected by the iteration count, which gives a huge difference, even if the attacker has both the password and the salt. – Support Monica - SpiritBob Aug 26 at 15:35

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.