rajaram_s
rajaram_s

Reputation: 357

How do I recompute web2py's password hash?

I am trying to have another application (running on a different stack) authenticate with an existing application of mine that runs of web2py. I am trying to understand how can I validate the entered password with the one that I have in auth_user?

I did see https://groups.google.com/forum/#!topic/web2py/tLAiqRaXG48 but I was unable to get the has from there. Here is what I am doing:

import hashlib from pbkdf2 import crypt crypt(hashlib.sha512("MyPassword").hexdigest(),iterations=1000)

My password in the db reads like this :

pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1

(slightly changed the hash itself)

Any help would be much appreciated.

Thanks, Rajaram

Upvotes: 1

Views: 490

Answers (1)

Anthony
Anthony

Reputation: 25536

First, note that the value stored in the password field is not just the final hashed value but includes the algorithm, the per-user salt, and the final hashed value (all delimited by the $ symbol). So, assuming we have:

stored_password = 'pbkdf2(1000,20,sha512)$b787f1e6dfe7da8f$b280b42a152aa14a1944d35c6a070521251b85d1'

start by doing something like:

_, salt, hashed_password = stored_password.split('$')

Now, because pbkdf2 was used, we must use hashlib.pbkdf2_hmac to compare the hashes:

from hashlib import pbkdf2_hmac
entered_password = 'MyPassword'
is_match = hashed_password == pbkdf2_hmac('sha512', entered_password, salt,
                                          rounds=1000, dklen=20).encode('hex')

Alternatively, if you don't mind copying the web2py validators.py module to the other system, you can simply do:

from validators import CRYPT
is_match = CRYPT()(entered_password)[0] == stored_password

Note, CRYPT() is a callable object (like all the web2py validators). When you call it with the entered password, it returns a tuple, the first element of which is a LazyCrypt object. The LazyCrypt class has implemented its own __eq__ special method, so the == comparison above triggers that method. It automatically extracts the digest algorithm, salt, and hash from stored_password, computes the hash of entered_password, and compares that to the hash extracted from stored_password (i.e., everything that was done manually in the solution above).

Upvotes: 3

Related Questions