Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate passwords in Python 2 and Python 3? Securely?

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?

like image 652
Vladimir Ignatyev Avatar asked Jan 31 '17 23:01

Vladimir Ignatyev


People also ask

Is Python Getpass secure?

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.

What is strong password in Python?

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].


1 Answers

Python 2

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])

Python 3

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)])
like image 61
Vladimir Ignatyev Avatar answered Oct 06 '22 00:10

Vladimir Ignatyev