title: ASP.NET membership HashAlgorithmType defaults to HMACSHA256, so is password hash keyed?
body: <p>I have an ASP.NET 4.5 web application that uses a <code>SqlMembershipProvider</code>. During development, someone put <code>passwordFormat="Clear"</code> in the config causing the passwords to be saved in clear text. I want to remove this and enable hashing of passwords, but I want to make sure the hashes are not being generated using a machine-specific, or auto-generated key. </p>
  
  <p>According to what I read on all the related Q&amp;A, the passwords are simply hashed using straight SHA256 and are not machine-specific or keyed. However, when I check the Membership.HashAlgorithmType at runtime, its value is "HMACSHA256" and the .NET <a href="https://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256(v=vs.110).aspx" rel="noreferrer"><code>HMACSHA256</code> class</a> requires a key (because it's HMAC) and randomly generates one if one is not provided to the constructor. So it seems there must be a key involved. So is the Membership password hash keyed or not? If it is, how do I use the same key across machines? Documentation or evidence supporting your answer will be appreciated.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>According to <a href="https://msdn.microsoft.com/en-us/library/ms178398(v=vs.100).aspx" rel="noreferrer">this MSDN page on "Securing Membership"</a>, the machineKey element <em>does</em> control the hash key:</p>
  
  <blockquote>
    <p>It is highly recommended that you encrypt user passwords in the membership data source using a passwordFormat attribute set to Hashed or Encrypted, where Hashed is the most secure format. The encryption key values for the specified encryption algorithm are stored in the machineKey configuration element.</p>
  </blockquote>
  
  <p>However, I tried setting the machine key validation key in the web.config and it still generated the same password hash as before it was set so it seems to have no effect.</p>
  
  <p>I have also been looking at the <a href="http://referencesource.microsoft.com/#System.Web/Security/SQLMembershipProvider.cs,3c3bf28c244d3130" rel="noreferrer">SqlMembershipProvider source code</a> and as far as I can tell, it does use a keyed hash. Granted that is the source for .Net 4.6.1 and I am running 4.5. I've copied the <code>EncodePassword</code> source code and modified it so it can run in a console app and in my console app I still get a different hash than the MembershipProvider result (on the same machine) for the same password and salt value. </p>
  
  <p>If it was using a random key, you wouldn't be able to validate passwords. So where does the SqlMembershipProvider get it's hash key from??</p>