5

Is it enough to use this method with SHA256 or it is better to use Rfc2898DeriveBytes (which orginally uses SHA1)?

 public static byte[] ComputeHash(byte[] data, byte[] salt, int iterations) { if (data == null) throw new ArgumentNullException(nameof(data)); if (salt == null) throw new ArgumentNullException(nameof(salt)); if (iterations <= 0) throw new ArgumentOutOfRangeException(nameof(iterations)); using (SHA256CryptoServiceProvider provider = new SHA256CryptoServiceProvider()) { byte[] output = provider.ComputeHash(data.Concat(salt).ToArray()); for (int iteration = 1; iteration < iterations; iteration++) { output = provider.ComputeHash(output.Concat(data).Concat(salt).ToArray()); } return output; } } 

Can above code be used instead of Rfc2898DeriveBytes from point of view of security? Will hashes have more or less entropy? Will it have more or less complexity (CPU/GPU/ASIC time) if I will use significantly big iterations parameter?

9
  • 1
    The context of your question is missing. Without this context it is unknown what you are trying to achieve and what "better" would mean in relation to your unknown goal.CommentedSep 8, 2016 at 6:23
  • "data" is byte-array converted from string meaning password, "salt" is RNGCryptoServiceProvider value (32 bytes), "iterations" is 65 535... I mean does it enough to get the same entropy as Rfc2898DeriveBytes and will it be OK to control complexity with big count of iterations.
    – Maxim
    CommentedSep 8, 2016 at 6:33
  • Information essential to understand the question belong in the question itself and not in a comment. Apart from that I don't mean context in terms of data structures but what you want to do, i.e. password check, key derivation...CommentedSep 8, 2016 at 6:42
  • Hash will be computed to be saved in database (initial key derivation when account is just created). And during password check it will be generated from string which is typed by user who attempts to login. Maybe I misunderstood something but for me it looks pretty clear as well as parameters of this method )))
    – Maxim
    CommentedSep 8, 2016 at 6:55
  • 1
    @Maxim You mentioned in in passing in a comment that this was going to be used for hashing passwords, but that's nowhere in the question. This is quite important, as that's not the primary purpose of Rfc2898DeriveBytes, which is password-based key derivation. Password hashing is a secondary use, and different security properties and considerations apply.
    – Xander
    CommentedSep 8, 2016 at 11:46

2 Answers 2

7

Use the known, trusted algorithm over one that you've made yourself.**

I can't speak for the entropy, but of course it will take more time if you have a sufficiently large number of iterations. It's just a matter of finding that number. That being said, I personally would not use your SHA256-based code.

As has been said in what is probably my favourite answer on security.SE: Complexity is bad. Homemade is bad. New is bad. From that same answer, Rfc2898DeriveBytes is PBKDF2, and PBKDF2:

  • Has been specified for a long time, seems unscathed for now.
  • Is already implemented in various framework (e.g. it is provided with .NET).
  • Highly configurable (although some implementations do not let you choose the hash function, e.g. the one in .NET is for SHA-1 only).
  • Received NIST blessings (modulo the difference between hashing and key derivation; see later on).

Why would you want to write your own - potentially buggy, potentially vulnerable, definitely unnecessary - crypto code when there is already code written for you that has been tested, attacked, and demonstrated to be good?

Further reading:

2
  • I think you are arguing really good. I will mark it as answer )) But I still do not see any mathematical analyzing which says why SHA256 & salt with feedback is bad. Your attempt to offer standard algorithms of course makes sense... But most likely I need to look at Argon2. But there are no pure .Net implementation. Still think that is bad to port it from C++ to C#? ))
    – Maxim
    CommentedSep 9, 2016 at 3:30
  • Since version 4.7.2 it is possible to specify the algorithm through HashAlgorithmName -> constructorCommentedFeb 8, 2020 at 11:26
1

It seems you want SHA256 because it is more secure than SHA1, but you also want PBKDF2 because it is more secure than a single hash. Solution: use PBKDF2 with SHA256.

1
  • Yes, most likely it can be an option.. and I considered that already... But original idea is not single hash.. it is multiple hashes with salt and feedback, when output is used on input during next iteration... with salt and password. So I am trying to figure if it is enough to be secure...
    – Maxim
    CommentedSep 8, 2016 at 6:47

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.