Question

Using: Python 3.2.3, scrypt 0.5.5 module, Ubuntu 12.04

I installed the scrypt module fine. I ran the sample code on the page fine. I also found an expanded version of the sample code, which did fine too. But I wanted to test if it would hash the same word twice, so I added a section call to Encrypt(), to simulate the concept of hashing it once for the DB and then hashing again when a user logs in, so my full code looks like this:

import random,scrypt

class Encrypt(object):

    def __init__(self):
        pass

    def randSTR(self,length):
        return ''.join(chr(random.randint(0,255)) for i in range(length))

    def hashPWD(self,pwd, maxtime=0.5, datalength=64):
        return scrypt.encrypt(self.randSTR(datalength), pwd, maxtime=maxtime)

    def verifyPWD(self,hashed_password, guessed_password, maxtime=0.5):
        try:
            scrypt.decrypt(hashed_password, guessed_password, maxtime)
            return True
        except scrypt.error:
            return False

if __name__ == '__main__':
    e = Encrypt()
    user_pw = 'theansweris42'
    user_salt = 't9'
    pw_salt = user_pw + user_salt
    hashed_pw = e.hashPWD(pw_salt) # To be stored len()==192
    y = e.verifyPWD(hashed_pw, pw_salt)              # True
    n = e.verifyPWD(hashed_pw, 'guessing'+ pw_salt)  # False
    print(y)
    print(n)
    #print("Hash: %s" % (hashed_pw))

    x = Encrypt()
    user_pw2 = 'theansweris42'
    user_salt2 = 't9'
    pw_salt2 = user_pw2 + user_salt2
    hashed_pw2 = x.hashPWD(pw_salt2) # To be stored len()==192
    y2 = x.verifyPWD(hashed_pw, hashed_pw2)              # True
    print(y2)
    print(pw_salt)
    print(pw_salt2)
    print(hashed_pw)
    print(hashed_pw2)

...as you can see, I also hard coded the salt (for testing). Strangely, everytime I run this, the hashed_pw & hashed_pw2 are always different. Why is this hashing the same password differently each time? Shouldn't it be outputting the same hash each time I give it the exact same input? I've been trying to figure this out for an hour, so I figure I better ask.

Was it helpful?

Solution

You encrypt two different random strings with the same password (plus a salt). This will result in two different outputs.

The trick used here is that the password + salt can be used to decrypt that random string, while the incorrect password will raise an error. Hence, you don't need to store the original random string to make sure that the password was correct, and since the string used was random (within the limits of the random number generator) it's going to be extremely hard to crack the password.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top