Ubuntu Python 3,Scrypt模块,哈希不匹配

Ubuntu Python 3,Scrypt模块,哈希不匹配,ubuntu,python-3.x,scrypt,Ubuntu,Python 3.x,Scrypt,使用:Python 3.2.3、Scrypt0.5.5模块、Ubuntu 12.04 我很好地安装了scrypt模块。我在页面上很好地运行了示例代码。我还找到了一个,也不错。但我想测试它是否会对同一个单词进行两次散列,因此我添加了一个对Encrypt()的节调用,以模拟对DB进行一次散列,然后在用户登录时再次进行散列的概念,因此我的完整代码如下所示: import random,scrypt class Encrypt(object): def __init__(self):

使用:Python 3.2.3、Scrypt0.5.5模块、Ubuntu 12.04

我很好地安装了scrypt模块。我在页面上很好地运行了示例代码。我还找到了一个,也不错。但我想测试它是否会对同一个单词进行两次散列,因此我添加了一个对Encrypt()的节调用,以模拟对DB进行一次散列,然后在用户登录时再次进行散列的概念,因此我的完整代码如下所示:

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)

…如您所见,我还硬编码了salt(用于测试)。奇怪的是,每次我运行这个,hash_pw和hash_pw2总是不同的。为什么每次对同一密码进行散列时会有所不同?每次我给它完全相同的输入时,它不应该输出相同的散列吗?我已经花了一个小时试图弄明白这一点,所以我想我最好问一下。

您使用相同的密码(加上一个salt)加密两个不同的随机字符串。这将导致两种不同的输出


这里使用的技巧是密码+salt可以用来解密该随机字符串,而不正确的密码将引发错误。因此,您不需要存储原始随机字符串以确保密码正确,而且由于使用的字符串是随机的(在随机数生成器的限制范围内),破解密码将非常困难。

您使用相同的密码加密两个不同的随机字符串(加上一个salt)。这将导致两种不同的输出


这里使用的技巧是密码+salt可以用来解密该随机字符串,而不正确的密码将引发错误。因此,您不需要存储原始随机字符串以确保密码正确,而且由于使用的字符串是随机的(在随机数生成器的限制范围内),因此破解密码将非常困难。

我想我没有理解一些东西。我对这个有点陌生,所以如果我问了一些“愚蠢”的问题,我道歉,但是。。。如何加密两个不同的随机字符串?这不是在对字符串进行哈希运算吗?答案是42t9,两次都是?这个字符串是
pw_salt
pw_salt2
的值,所以当我对它们进行散列时,它应该输出相同的值,对吗?另外,我必须在数据库中存储一些东西(散列的pwd&salt?),以便稍后用户登录时比较,对吗?@Zamphatta:不,你加密的字符串是self.randSTR(datalength)。是的,你需要储存土豆条和盐。但是你没有比较任何东西,你只是用密码和盐解密存储的散列。哦,我明白了。哇,这和我想的完全不同。我喜欢!我想我必须散列pwd和salt,将其存储在数据库中,然后当用户登录时,我重新散列pwd和salt,以便将其与数据库中存储的值进行比较。所以我感到困惑&我不明白。我过去就是这样做的&我认为这是唯一合乎逻辑的方法。我比以前更喜欢这种方式。谢谢Lennart!我想我不明白什么。我对这个有点陌生,所以如果我问了一些“愚蠢”的问题,我道歉,但是。。。如何加密两个不同的随机字符串?这不是在对字符串进行哈希运算吗?答案是42t9,两次都是?这个字符串是
pw_salt
pw_salt2
的值,所以当我对它们进行散列时,它应该输出相同的值,对吗?另外,我必须在数据库中存储一些东西(散列的pwd&salt?),以便稍后用户登录时比较,对吗?@Zamphatta:不,你加密的字符串是self.randSTR(datalength)。是的,你需要储存土豆条和盐。但是你没有比较任何东西,你只是用密码和盐解密存储的散列。哦,我明白了。哇,这和我想的完全不同。我喜欢!我想我必须散列pwd和salt,将其存储在数据库中,然后当用户登录时,我重新散列pwd和salt,以便将其与数据库中存储的值进行比较。所以我感到困惑&我不明白。我过去就是这样做的&我认为这是唯一合乎逻辑的方法。我比以前更喜欢这种方式。谢谢Lennart!