Python crypt模块

2024-04-28 19:50:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我在查找python模块时,发现了一个叫做crypt的东西。我不明白。我试过阅读这个,什么是“salt”的东西,这个crypt模块的用途是什么,有没有什么方法可以对这段python代码应用“crypt”?以下内容:

import crypt

max_attempts = 3     
attempt = 0          

try:


    while attempt < max_attempts:

        uname = input('Username: ')  
        password = input('pass: ')   

        if uname == 'admin' and password == 'Khs9':
            print('Welcome Admin')
            break
        else:
            attempt += 1
            if attempt == max_attempts:
                raise RuntimeError("\nYou've reached the maximum number of attempts allowed.")

            else:
                print('Wrong credentials.\n Try again or press <ctrl+c> to exit.\n')
                continue


except keyboardInterrupt:
    print('Terminated by the user.\nGood-bye.')

except RuntimeError as e:
    print("Goodbye")

Tags: 模块theinputifpasswordelsemaxsalt
2条回答

首先,请阅读Thomas Pornin's canonical answer to How to securely hash passwords。这将回答你关于“盐”是什么的问题。

第二,密码是一种古老的算法-不要使用它。即使是基于Python SHA-512的crypt也可能无法使用,因为您无法控制迭代次数(BCrypt可能称之为工作因子),因此您无法通过增加迭代次数来使其更安全。

第三,Python as of 3.4 has fast PBKDF2 based on OpenSSL built in

Python 2.7.8也是。

这两种方法都支持在hashlib中构建合理的哈希类型!用这些来代替!如何使用这些工具的一个例子如下:

import hashlib

BinaryOutput = hashlib.pbkdf2_hmac('sha512',password, salt, args.iterations, args.outputBytes)

其中

  • args.iterations在低位数十万到高位数万之间

  • 假设使用的是SHA-512,那么args.outputBytes不超过64个(其他算法更少),并且不少于20个。

  • 将迭代次数存储在cleartext中(无论是硬编码的、文件中的还是数据库中的),这样以后就可以很容易地使它变大。

  • 为了得到salt,您应该生成至少12个(最好是至少16个)加密随机字节。对每个用户名使用不同的salt,并将其存储在存储中的明文中(无论是硬编码的、文件中还是数据库中)。

使用PBKDF2-HMAC-SHA-512使用64位操作,这会降低基于GPU的攻击者对您的优势。

如果您担心定时攻击,可以使用各种恒定时间比较之一。一个与高迭代PBKDF2-HMAC-SHA-512相比不需要花费太多的东西是这样的:

if hashlib.sha256(args.expectedBinary).hexdigest() == hashlib.sha256(BinaryOutput).hexdigest():

现在我看到你的代码了,我知道密码是'Khs9',我可以登录到你的邮箱。

你可以私下运行以下命令。

>>> crypt.crypt('Khs9', 'aa')
'aa0GPiClW35DQ

现在更新代码:

import crypt

max_attempts = 3     
attempt = 0          
stored_pw_hash = 'aa0GPiClW35DQ'

try:


     while attempt < max_attempts:

        uname = input('Username: ')  
        entered_pw_hash = crypt.crypt(input('pass: '), stored_pw_hash)

        if uname == 'admin' and entered_pw_hash == stored_pw_hash:
            print('Welcome Admin')
            break
        else:
            attempt += 1
            if attempt == max_attempts:
                raise RuntimeError("\nYou've reached the maximum number of attempts allowed.")

            else:
                print('Wrong credentials.\n Try again or press <ctrl+c> to exit.\n')
                continue


except KeyboardInterrupt:
    print('Terminated by the user.\nGood-bye.')

except RuntimeError as e:
    print("Goodbye")

如果你的代码泄露了,他们就不能马上访问。你应该有足够的时间意识到你被黑客攻击,然后更改你的密码。

这是背景资料。。。

crypt.crypt(密码)将返回密码的哈希值。存储散列而不是明文密码。这样,你就不能因为没有密码就把密码丢给黑客。丢失散列不是大问题,因为它不能保证访问(如果遵循最佳实践,包括使用salt)。

下次有人提供密码时,你会计算出它的哈希值,并将其与之前存储的哈希值进行比较,如果它们匹配,你就会知道他们给了你正确的密码。

你为什么要用盐? 因为有人花了很长时间生成一个包含常用密码和散列的表。一旦完成,这是一个快速检查破解杂凑。通过使用salt,您可以确保应用不同的查找表,一个可能不可用的查找表,并且普通黑客没有时间生成它。

crypt.crypt()需要两个字符才能用作盐。可以向它传递一个两个字符的字符串,也可以使用函数的前一个输出。(crypt.crypt()返回一个字符串,前两个字符是salt,其余字符是hash)

我看着https://docs.python.org/3.4/library/crypt.html回答这个问题。

相关问题 更多 >