High quality, simple random password generator

前端 未结 27 2357
渐次进展
渐次进展 2020-12-22 17:06

I\'m interested in creating a very simple, high (cryptographic) quality random password generator. Is there a better way to do this?

import os, random, strin         


        
相关标签:
27条回答
  • 2020-12-22 17:31

    There are some problems with your implementation:

    random.seed = (os.urandom(1024))
    

    This does not seed the random number generator; it replaces the seed function with a bytestring. You need to call seed, like, random.seed(…).

    print ''.join(random.choice(chars) for i in range(length))
    

    Python's default PRNG is a Mersenne Twister, which is not a cryptographically strong PRNG, so I'm wary of using it for cryptographic purposes. The random module includes random.SystemRandom, which on at least most *nix systems, should use a CSPRNG. However,

    random.choice(chars)
    

    …is implemented as…

    def choice(self, seq):
        """Choose a random element from a non-empty sequence."""
        return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
    

    …in Python 2. Unfortunately, self.random here is a C function, so this gets hard to see; the code smell here is that this code almost certainly doesn't choose uniformly. The code has completely changed in Python 3, and does a much better job of ensuring uniformity. The Python 3 docs for randrange note,

    Changed in version 3.2: randrange() is more sophisticated about producing equally distributed values. Formerly it used a style like int(random()*n) which could produce slightly uneven distributions.

    randrange and choice both call the same method (_randbelow) under the hood.

    In Python 3, choice is fine; in Python 2, it only comes close to a uniform distribution, but does not guarantee it. Since this is crypto, I lean on the "take no chances" side of the fence, and would like to have that guarantee.

    0 讨论(0)
  • 2020-12-22 17:32

    A little bit off topic, but I made this, using also TKinter. Hope it can helps:

    import os, random, string
    from tkinter import *
    
    def createPwd():
        try:
            length = int(e1.get())
        except ValueError:
            return
        chars = string.ascii_letters + string.digits + '!@#$%^&*()?\/'
        random.seed = (os.urandom(1024))
        e2.config(state=NORMAL)
        e2.delete(0,'end')
        e2.insert(0,''.join(random.choice(chars) for i in range(length)))
        e2.config(state="readonly")
    
    mainWindow = Tk()
    mainWindow.title('Password generator')
    
    mainWindow.resizable(0,0)
    
    f0 = Frame(mainWindow)
    
    f0.pack(side=TOP,pady=5,padx=5,fill=X,expand=1)
    
    Label(f0,text="Length: ",anchor=E).grid(row=0,column=0,sticky=E)
    
    e1 = Entry(f0)
    e1.insert(0,'12')
    e1.grid(row=0,column=1)
    
    btn = Button(f0,text="Generate")
    btn['command'] = lambda: createPwd()
    btn.grid(row=0,column=2,rowspan=1,padx=10,ipadx=10)
    
    Label(f0,text="Generated password: ",anchor=E).grid(row=1,column=0,sticky=E)
    e2 = Entry(f0)
    e2.grid(row=1,column=1)
    
    createPwd()
    
    #starting main window
    mainWindow.mainloop()
    
    0 讨论(0)
  • 2020-12-22 17:34

    That way works. It is perfectly fine. If you had additional rules, such as excluding dictionary words, then you may want to include those filters as well, but the likelihood of randomly generating a dictionary word with that setup is extremely small.

    0 讨论(0)
提交回复
热议问题