【问题标题】:Use Fernet/os.urandom key to generate passwords使用 Fernet/os.urandom 密钥生成密码
【发布时间】:2021-09-08 15:32:21
【问题描述】:

所以我做了一个密码生成器

char = random.choice(string.punctuation)
numb = str(random.randrange(0, 10))
upper = random.choice(string.ascii_uppercase)
lower1 = random.choice(string.ascii_lowercase)
lower2 = random.choice(string.ascii_lowercase)
lower3 = random.choice(string.ascii_lowercase)
lower4 = random.choice(string.ascii_lowercase)
lower5 = random.choice(string.ascii_lowercase)
lower6 = random.choice(string.ascii_lowercase)
lower7 = random.choice(string.ascii_lowercase)
print("Your randomly generated password is:",
char + numb + upper + lower1 + lower2 + lower3 + lower4 + lower5 + lower6 +lower7)

然后我被卷入了一个密码学的虫洞,我安装了库并尝试使用 fernet 创建一个加密密钥。

修补了几个小时后,我碰壁了。

我想使用 fern 提供的加密随机字节来构建我的密码,但密码长度为 44 个字符,有时不包括大写/符号等。

试过

p = os.random(4) 

这解决了长度问题,但有时仍会吐出无法使用的密码。

如何使用os.urandom 构建一个可行的 12 字符密码

(1个大写,1个小写,1个符号,1个数字)

【问题讨论】:

  • 您是否只想使用os.urandom。因为您的代码可以简化为足够好的解决方案。
  • 改用secrets。可怕的名字,但我猜random 已经被占用了。请注意,如果您开始计算变量名,那么您做错了:计算机应该进行计数,而不是您:)
  • 顺便说一句,如果您想在密码中包含特定数量的项目,您可能需要安全地洗牌。 Here's a way to do that 但将 sample 替换为 secrets.belowThingy 方法。

标签: python cryptography


【解决方案1】:

我猜您想专门使用os.urandom 来构建具有特定规格的密码,至少是一个大写、一个小写、一个数字和一个符号。

import os

alphabet = 'qwertyuioplkjhgfdaszxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789!@#$%^&*()'
upper = 'QAZWSXEDCRFVTGBYHNUJMIKLOP'
lower = 'qwertyuioplkjhgfdaszxcvbnm'
numbers = '0123456789'
symbols = '!@#$%^&*()'

length = len(alphabet)
password = ''
password_length = 10
for x in range(password_length):
    password += alphabet[int.from_bytes(os.urandom(1), byteorder="big") % length]

flags = []
for x in upper:
    if x in password:
        flags.append(1)
        break

for x in lower:
    if x in password:
        flags.append(1)
        break

for x in numbers:
    if x in password:
        flags.append(1)
        break

for x in symbols:
    if x in password:
        flags.append(1)
        break

if len(flags) == 4:
    print("your password is ready: ", password)

因为密码首先是随机生成的,然后检查它是否符合某些标准,有时测试会失败,特别是如果密码长度很短,您将不得不再次运行程序。

【讨论】:

  • 刚刚看到这个现在我找到了另一个解决方案,但我很欣赏你所做的工作,我想我会尝试从字节中获取 int,以便很快将 Fernet 密钥生成器转换为密码字符串:O!
【解决方案2】:

感谢那些给我想法的人,我自己找到了答案

虽然我无法找到将 Fernet 字节数据直接转换为密码的方法,但我对密码学进行了更深入的研究,并了解了真正随机与伪随机的原因。

以下代码是我为将来遇到与我相同的问题的任何人确定的。

它的作用:

  • 接受用户的输入
  • 检查输入是否为整数
  • 然后将数字向下舍入到可被 4 整除的最接近的整数
  • 最后按顺序生成大写/小写/数字/标点符号。

这是一个有趣的项目,我一定会很快重新审视它,以使其更简单、更高效,如果您有任何想法,请不要害羞地给我留言!

    # Cryptographically generated random password
    
    import random
    import string

    # Start Passgen

    print("Please input a max-character limit for required password")
    size = input()
    try:
        val = int(size)
    except ValueError:
        print("That's not an int!")

    else:
        print("Input accepted, Now generating password...")

    # Generate the Password
    def pass_gen():

        uletters = string.ascii_uppercase
        lletters = string.ascii_lowercase
        digits = string.digits
        punctuation = string.punctuation
        chars = (uletters, lletters, digits, punctuation)
        p = ''

        for i in range(int(size)//4):

    p += ''.join(random.SystemRandom().choices(uletters, k=1))
    p += ''.join(random.SystemRandom().choices(lletters, k=1))
    p += ''.join(random.SystemRandom().choices(digits, k=1))
    p += ''.join(random.SystemRandom().choices(punctuation, k=1))
        print("Your randomly generated password is: " + p)

        #Run the function
        pass_gen()

【讨论】: