17

I would like to get a few opinions on whether it would be safe or not to use PBKDF2 to generate a hash of a password. For my purposes I'd like to assume that the hash itself will be posted on the White House Twitter page (in other words it will be public).

Would I be better off using a massive number of SHA-256 iterations (as a replacement for my 100,000 PBKDF2 iterations)? Are there any attacks that can reverse PBKD2?

This is the code I'm using:

        string salt = Utility.RandString(32);
        // convert to byte[] and store in both forms
        this.Salt = salt;
        this.BSalt = Utility.ToByteArray(salt);
        // generate the password hash
        Rfc2898DeriveBytes preHash = new Rfc2898DeriveBytes(this.Password,  this.BSalt, 100000);
        byte[] byteHash = preHash.GetBytes(32);
        this.Hash = Convert.ToBase64String(byteHash);
Razick
  • 357
  • 1
  • 2
  • 7

2 Answers2

21

The short answer is that PBKDF2 is considered appropriate and secure for password hashing. It is not as good as could be wished for because it can be efficiently implemented with a GPU; see this answer for some discussion (and that one for more on the subject).

There are some arguable points, notably that PBKDF2 was designed to be a Key Derivation Function, which is not the same kind of animal as a hash function; but it turned out to be quite usable for password hashing as well, provided that you do not do anything stupid with it (meaning: be sure to keep at least 80 bits of output, and to use a high enough iteration count, ideally as high as you can tolerate on your hardware).

Don't try to make your own hash function; these things are surprisingly hard to get right, especially because it is nigh impossible to assess whether a given construction is secure or not. Use PBKDF2. If you really want SHA-256 (or SHA-512), then use PBKDF2 with SHA-256: PBKDF2 is a configurable construction, which is traditionally configured to use SHA-1, but works equally well with SHA-256 or SHA-512.

Tom Leek
  • 168,808
  • 28
  • 337
  • 475
  • What would you recommend for hashing that is available in both C# and PHP? – Razick Dec 17 '13 at 18:19
  • 7
    **PBKDF2 cannot be efficiently implemented on a GPU because of the XOR operation performed between each iteration of the hash function.** – rook Dec 17 '13 at 18:25
  • 10
    @Rook: ah, a context-dependent misunderstanding. PBKDF2 fits well on a GPU _in the context of password cracking_, because you can run many PBKDF2 instances in parallel. What would not work well would be using a GPU to run _one_ PBKDF2 (the algorithm is very sequential) but the attacker has millions of PBKDF2 instances to run, and these instances are independent of each other. Bcrypt, on the other hand, does not run well on a GPU, because it uses a RAM lookup table and this implies a lot of bus contention (the independent instance have to share the same scarce bus resources). – Tom Leek Dec 17 '13 at 18:54
  • @rook Can you provide a source to back this up? XOR operators are as quick as anything else. (For example, CUDA calling native operators: http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#arithmetic-instructions__throughput-native-arithmetic-instructions) – Nicolas Sep 12 '16 at 09:44
  • Can you update this answer? – Martin Thoma Oct 16 '20 at 16:55
2

I think it is a good KDF though there are better ones.

The password entropy itself is of greater importance.

http://arstechnica.com/security/2013/05/how-crackers-make-minced-meat-out-of-your-passwords/

If you can remember your password, special shortcut techniques can be used that lower the theoretical strength of the password. Basically think of words as a single character when it comes to calculating entropy.

A 6 character password with a really high cost KDF will still be cracked in no time.

Andrew Hoffman
  • 1,987
  • 14
  • 17