Reputation: 357
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
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