title: Verify Python Passlib generated PBKDF2 SHA512 Hash in .NET
body: <p>I am migrating a platform which used <a href="http://pythonhosted.org/passlib/" rel="nofollow noreferrer">Passlib 1.6.2</a> to generate password hashes. The code to encrypt the password is (hash is called with default value for rounds):</p>
  <pre><code>from passlib.hash import pbkdf2_sha512 as pb
  
  def hash(cleartext, rounds=10001):
      return pb.encrypt(cleartext, rounds=rounds)
  </code></pre>
  <p>The output format looks like (for the password &quot;Patient3&quot; (no quotes)):</p>
  <pre><code>$pbkdf2-sha512$10001$0dr7v7eWUmptrfW.9z6HkA$w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p/b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7.hg
  </code></pre>
  <p>And &quot;Testing123&quot;</p>
  <pre><code>$pbkdf2-sha512$10001$2ZuTslYKAYDQGiPkfA.B8A$ChsEXEjanEToQcPJiuVaKk0Ls3n0YK7gnxsu59rxWOawl/iKgo0XSWyaAfhFV0.Yu3QqfehB4dc7yGGsIW.ARQ
  </code></pre>
  <p>I can see that represents:</p>
  <ul>
  <li>Algorithm SHA512</li>
  <li>Iterations 10001</li>
  <li>Salt 0dr7v7eWUmptrfW.9z6HkA (possibly)</li>
  </ul>
  <p>The Passlib algorithm is defined on <a href="https://pythonhosted.org/passlib/lib/passlib.hash.pbkdf2_digest.html#passlib.hash.pbkdf2_sha512" rel="nofollow noreferrer">their site</a> and reads:</p>
  <blockquote>
  <p>All of the pbkdf2 hashes defined by passlib follow the same format, $pbkdf2-digest$rounds$salt$checksum.</p>
  <p>$pbkdf2-digest$ is used as the Modular Crypt Format identifier ($pbkdf2-sha256$ in the example).
  digest - this specifies the particular cryptographic hash used in conjunction with HMAC to form PBKDF2’s pseudorandom function for that particular hash (sha256 in the example).
  rounds - the number of iterations that should be performed. this is encoded as a positive decimal number with no zero-padding (6400 in the example).
  salt - this is the adapted base64 encoding of the raw salt bytes passed into the PBKDF2 function.
  checksum - this is the adapted base64 encoding of the raw derived key bytes returned from the PBKDF2 function. Each scheme uses the digest size of its specific hash algorithm (digest) as the size of the raw derived key. This is enlarged by approximately 4/3 by the base64 encoding, resulting in a checksum size of 27, 43, and 86 for each of the respective algorithms listed above.</p>
  </blockquote>
  <p>I found <a href="https://www.nuget.org/packages/Passlib.NET/" rel="nofollow noreferrer">passlib.net</a> which looks a bit like an abandoned beta and it uses '$6$' for the algorithm. I could not get it to verify the password. I tried changing the algorithm to $6$ but I suspect that in effect changes the salt as well.</p>
  <p>I also tried using <a href="https://sourceforge.net/projects/pwdtknet/" rel="nofollow noreferrer">PWDTK</a> with various values for salt and hash, but it may have been I was splitting the shadow password incorrectly, or supplying $ in some places where I should not have been.</p>
  <p>Is there any way to verify a password against this hash value in .NET? Or another solution which does not involve either a Python proxy or getting users to resupply a password?</p>