title: Key Strengthening. Am I Doing It Right?
body: <p>I am writing a class to hash passwords which implements <a href="http://en.wikipedia.org/wiki/Key_stretching">Key Stretching</a> by using the System.Security.Cryptography.Rfc2898DeriveBytes class to generate the keys used to compute the hash value.</p>
  
  <p>The code essentially does this:</p>
  
  <pre><code>// Higher iterations value results in better key strength
  var db = new Rfc2898DeriveBytes(password + salt + secretKeyFromConfigFile,
                                  saltAsBytes,
                                  iterations);
  
  byte[] hashKey = db.GetBytes(64); // 64 bytes is the recommended size for the HMACSHA512 class
  
  var sha512 = new System.Security.Cryptography.HMACSHA512(hashKey);
  
  byte[] hashInput = System.Text.Encoding.UTF8.GetBytes(password + salt + secretKeyFromConfigFile);
  
  byte[] hash = sha512.ComputeHash(hashInput);
  
  return System.Convert.ToBase64String(hash);
  </code></pre>
  
  <p>The documentation for System.Security.Cryptography.Rfc2898DeriveBytes indicates that it uses "... a pseudo-random number generator based on System.Security.Cryptography.HMACSHA1" to derive the key.</p>
  
  <p>Since SHA512 is better than SHA1 Would it be better to simply apply the SHA512 hash function like so?</p>
  
  <pre><code>byte[] hash;
  
  for (int i = 0; i &lt; iterations; i++)
  {
      hash = sha512.ComputeHash(hash ?? hashInput);
  }
  
  return System.Convert.ToBase64String(hash);
  </code></pre>
  
  <p>What is the difference between strengthening the key (as shown in the 1st code block) and strengthening the hash (as shown in the 2nd code block)?</p>
  
  <p>What is the preferred method to do key stretching when hashing passwords?</p>