Here on Stackoverflow exist at least one post related to this topic: Generate password in python
You can find that this topic found some critics even in PEP. It's mentioned here: https://www.python.org/dev/peps/pep-0506/
So, how to generate random passwords in Python 2 and Python 3 properly and securely?
getpass() and getuser() in Python (Password without echo) getpass() prompts the user for a password without echoing. The getpass module provides a secure way to handle the password prompts where programs interact with the users via the terminal.
Minimum 8 characters. The alphabet must be between [a-z] At least one alphabet should be of Upper Case [A-Z] At least 1 number or digit between [0-9].
As you may know, the random
module in Python 2 use insecure pseudo-random numbers generator. This is stated clearly in the warning on the official documentation page: "The pseudo-random generators of this module should not be used for security purposes."
The random
module is insecure, because its' internals, that rely on the algorithms (Mersenne Twister algorithm) seeded by the current time on host. Despite having good statistical characteristics of output, the output of such algorithms is highly predictable and vulnerable to Random Numbers Generators Attacks. If you don't believe to security professionals, check out this popular post: https://jazzy.id.au/2010/09/22/cracking_random_number_generators_part_3.html
The official documentation on Python 2 recommends to use os.urandom
function and SystemRandom
class, because they use more secure random numbers source provided by operating system.
Operating system generate pseudo-random numbers using the data from multiple sources, most of them are very unpredictable and having high entropy. os.urandom
on Linux uses output from /dev/urandom
device. You may check the official kernel documentation for details about /dev/urandom
and it's differences to /dev/random
. Also, if you use hardware random number generator, is it possible to use it as /dev/random
.
The answer on this question in Python 2 may look like this:
import os
def gen_password(length=8, charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"):
random_bytes = os.urandom(length)
len_charset = len(charset)
indices = [int(len_charset * (ord(byte) / 256.0)) for byte in random_bytes]
return "".join([charset[index] for index in indices])
The latest Python 3.6 has a module called secrets
. It is proposed in corresponding PEP-0506 by Steven D'Aprano. The purpose of this module is to provide "secure by default" cryptographic primitives suitable for modern applications and for "crypto-naive" users. Also it provides clean and straightforward API for cryptographic stuff.
Consider the following implementation of generating random passwords in Python 3.
import secrets
def gen_password(length=8, charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"):
return "".join([secrets.choice(charset) for _ in range(0, length)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With