Package: passwdgen
passwdgenOverviewpasswdgenis a simple password generation utility with a couple of
powerful extra features (including password entropy calculation and
entropy-based password generation).InstallationTo usepasswdgen, you will need to install Python 3.9+.>pipinstallpasswdgenIf you wantpasswdgento be globally accessible, you'll need to
install it withsudo/rootprivileges:>sudopipinstallpasswdgenUsageThe simplest password generation command you can execute is:>passwdgengenerate
totems-representing-sachem-tarrierCommandsTo find out more detailed help about a particular command, simply
run:>passwdgen<command>--help# For example:>passwdgengenerate--helpinfoAllows you to calculate the entropy of a particular password. For
example, on UNIX-like systems, you can simply pipe the password into
the info command:>echo"some-password"|passwdgeninfo
>cat/path/to/password/file|passwdgeninfoIf you do not pipe text intopasswdgen, it will prompt you to enter
the password on the command line:>passwdgeninfo
Pleaseenterthepasswordtocheck:<typeyourpasswordhere>For more information on password entropy, please see the section
onEntropyfurther on in this README.generateGenerate a password. Two kinds of passwords can be generated:dictionary-based passwords (the default), orcharacter-based passwords (see thisXKCDbefore you choose this mechanism).Some examples ofdictionary-basedpassword generation:# Generate a dictionary-based password 6 words long>passwdgengenerate-l6# Generate a dictionary-based password with minimum entropy 70 bits>passwdgengenerate-m70# Generate a dictionary-based password and copy it to the clipboard>passwdgengenerate-c# Generate a dictionary-based password with colons (:) as a separator>passwdgengenerate-scolon# Generate a dictionary-based password and display its entropy info>passwdgengenerate-i# Generate a dictionary-based password based on the given starting letters>passwdgengenerate--starting-lettershelloSome examples ofcharacter-basedpassword generation:# Generate a password 15 characters long comprising numbers and letters>passwdgengenerate-talpha-numeric-l15# Generate a password 18 characters long comprising numbers, letters and# special characters>passwdgengenerate-tspecial-l18# Generate a password 12 characters long and display its entropy info>passwdgengenerate-tspecial-l12-i# Generate a character-based password, copy it to the clipboard, and# display its entropy info>passwdgengenerate-tspecial-c-irngRuns a quick test of your OS' pseudorandom number generator (PRNG).
Computes a sample set (by default, 1 million entries) of random
numbers between 0 and 100 (inclusive)For example:>passwdgenrng
TestingOSRNG.Attemptingtogenerate1000000samplesbetween0and100(inclusive).Pleasewait...

Statistics
----------
Mean:49.966455(shouldapproach50.000asthesamplesizeincreases;0.067%difference)Standarddeviation:29.151161(shouldbeascloseto29.154759aspossible;0.012%difference)Timetaken:2.083secondsThe expected standard deviation for a random variable with a discrete
uniform random distribution is expected to be calculated as perthis Wikipedia entry.wordlistAt present, this command has only one sub-command:clean. To take
an arbitrary word list (a text file with one word per line) and
clean it up, do the following:>passwdgenwordlistclean/path/to/input/file.txt/path/to/output/file.txtThis command will:remove empty lines,strip out any plurals ('sat the end of strings),convert all words to lowercase,deduplicate entries, andsort everything alphabetically.APIUsingpasswdgenfrom your own Python project is easy:importpasswdgen# Generate a dictionary-based password using the built-in dictionarymy_password=passwdgen.words()# Generate a character-based passwordmy_password=passwdgen.chars()# Generate a dictionary-based password with 6 wordslong_password=passwdgen.words(word_count=6)# Generate a dictionary-based password with minimum entropy 80difficult_password=passwdgen.words(min_entropy=80)# Generate a dictionary-based password with a custom dictionarymy_dictionary=passwdgen.load_word_list("/path/to/my/dict.txt")password=passwdgen.words(my_dictionary)passwdgen.words(dict_set, separator, word_count, min_entropy, starting_letters)Generates a dictionary-based password. All arguments are keyword
arguments and are optional:dict_set: Asetcontaining all of the possible words from which to
generate a password. If not supplied, this will default to the
built-in dictionary.separator: The separator character to use between the words.
Default value:-(hyphen)word_count: The number of words to use when generating the password.
If not specified, andmin_entropyis not specified, this defaults
to4.min_entropy: The minimum required entropy of the generated
password. Ifword_countis specified, this parameter is ignored.starting_letters: A string containing the desired starting letters
of each word in the generated password. Note: ifword_countormin_entropyare specified, this string must contain at least
the relevant number of characters to match the number of generated
words. Otherwise the generated password will have exactly the same
number of words as this string has characters.Returns a string.passwdgen.chars(charset, length, min_entropy)Generates a character-based password. All arguments are keyword
arguments and are optional:charset: The ID of the character set from which to source characters
for the generated password. Default:special. See the
section onCharacter Setsbelow.length: The required number of characters in the generated password.
If neitherlengthnormin_entropyare specified, this defaults
to12.min_entropy: The minimum required entropy of the generated
password. Iflengthis specified, this parameter is ignored.Returns a string.passwdgen.load_word_list(filename, encoding)Loads a word list into memory. All arguments are keyword arguments
and are optional:filename: The path to the file from which to load the words. This
file must be a plain text file containing one word per line. If
not specified, this loads the built-in dictionary into memory.encoding: The character encoding to use when reading the file.Returns asetcontaining the loaded words.passwdgen.secure_random(a, b)Securely generates a random number using the given limits.a(required): Ifbis specified,arepresents the lower limit
(inclusive) of the resulting random number. Ifbis not specified,arepresents the upper limit (exclusive) of the generated number,
and the lower limit defaults to0.b(optional): The upper limit (exclusive) of the generated random
number.Returns a securely generated random number witha <= result < bifbis specified, or0 <= result < aifbis not specified.passwdgen.calculate_entropy(password, dict_set)Attempts to calculate the entropy of the given password based on
the preconfigured character sets and the dictionary.password(required): The password whose entropy is to be calculated.dict_set(optional): Asetof words comprising the dictionary
for which to perform the dictionary-based entropy calculation.Returns adictwhose keys represent the IDs of the different character
sets tested, and values represent the corresponding entropies.Character SetsThe following character sets are available at present (for use with thegenerate --charset <charset>command).dict: Dictionary-based password generation.alpha-lower: Lowercase alphabetical letters (a-z).alpha-upper: Uppercase alphabetical letters (A-Z).alpha: Alphabetical (a-z,A-Z).alpha-numeric: Alphanumeric characters (a-z,A-Z,0-9).alpha-numeric-spaced: Alphanumeric characters and spaces (a-z,A-Z,0-9,).numeric: Numeric characters (0-9).alpha-lower-sep: Lowercase alphabetical letters and separators
(a-z,-_. ,;:).alpha-upper-sep: Uppercase alphabetical letters and separators
(A-Z,-_. ,;:).special: Alphanumeric characters and special characters
(a-z,A-Z,0-9,-_. ,;:!@#$%^&*()+={}[]'\"\\/?<>`~).EntropyEntropy, in the context of information theory, provides a convenient
way to quantify the amount of information in a particular set of
data. With regard to password strength, the higher the entropy of
a password, the more difficult it is for an attacker to guess.From the perspective of the generator, the password strength is measured
by way of the information source. From the perspective of an attacker,
the more information is known about the information source that
generated the password (e.g. the kind of random number generator used,
the character set to which the password belongs), the lower the entropy
of that password.Secure random number generationEntropy calculations are based on the assumption that the random number
source is ofgood quality(seeCSPRNG)
and generatesuniformly distributedrandom numbers. The random number generator (RNG) used inpasswdis provided by theos.urandom()function, which uses/dev/urandomon POSIX systems andCryptGenRandom()on Windows systems.Character-based calculationThis password generator uses the following definition for entropy: a
single charactercfrom a character set of sizencharacters has
an entropy oflog2(n)bits (per character). Entropy adds up as the
length of the password increases, i.e. two characters from the character
set of sizenwill have a combined overall entropy of2 x log2(n).For example, if the lowercase alphabeta..zis used as the character
set, it hasn=26. Each character would have an entropy oflog2(26) = 4.700439718141093bits per character. A password string,
therefore, such asmysuperweakpasswordof length 19 characters, will
have a total entropy of19 x log2(26) = 89.31bits.As the size of the character set increases, so does the entropy of the
password of a certain length, as an attacker attempting a brute force
attack would have to search a much larger set of possibilities to
find the password.Dictionary-based calculationThe dictionary-based method of entropy calculation assumes that an
attacker has prior knowledge that the password was generated using a
dictionary of words, and even knows which dictionary was used. This
would obviously be the case if you personally usedpasswdgento
generate a dictionary-based password, as all the code and the dictionary
are out in the open.In this case, instead of assuming a character set (which would mean
a far higher entropy in passwords with 2 or more words), a
dictionary-based attack could be performed much quicker.For example, the passworddog-far-nightly-canis 19 characters long
and makes use of the lowercase alphabet and hyphens (resulting in a
character set of 27 possible characters). This means that a
brute force attacker using the full lowercase alphabet and hyphens
would be faced with a potential password entropy of19 x log2(27) = 90.34bits.If, however, the attacker knows that the password is dictionary-based
and that the words are separated by hyphens, the attacker would only
have to guess the 4 words from the dictionary making up the password.
This results in a potential entropy from the perspective of the
attacker of4 x log2(275,185) = 72.28bits (assuming dictionary
size of 275,185 words). This is still a pretty strong password, but
it is still easier to crack than a password where the attacker does not
know that it is dictionary-based.How much entropy is enough?So how does one select an appropriate entropy for trying to prevent
brute force attacks? This is difficult to estimate, because it depends
entirely on the resources available to an attacker. Usually it's cheaper
and easier to perform social engineering attacks if someone wants to
obtain your password, but if you're paranoid about security and want to
cover all your bases, you have to think about the kinds of computing
power available to attackers.Assuming that whichever service stores your password does not store the
clear password itself, but aSHA-256hash of the password (common practice today), and an attacker manages
to get hold of this SHA-256 hash, they will have to try many possible
permutations of input passwords that will eventually match to that
SHA-256 hash.In general,GPU-based hash attacks are much fasterthan CPU-based hash attacks. At the time of this writing, it would seem
as though high-end GPUs have the ability to perform around 1,000
megahashes per second (that's 1,000,000,000 hashes per second, or10^9hashes per second).Let's assume you generate a dictionary-based password, where the
source dictionary size is71,188words. Let's also assume that the
attacker has the same source dictionary, and knows which character you
use to separate the words in your password (in this case, a hyphen).WordsPermutationsTime to CrackEntropy25,067,660,1565.07 seconds32.24 bits3360,746,455,865,0164.175 days48.36 bits425,679,736,460,751,163,960814 years64.47 bits51,827,986,360,222,110,855,328,64057,965,067 years80.6 bitsOf course, if an attacker splits the work up evenly across multiple
GPUs, the time to crack goes down linearly, so a 4-word password being
brute-force cracked by 2 GPUs would take 407 years, 3 GPUs would take
203.5 years, 10 GPUs 81.4 years, 100 GPUs 8.1 years, 1,000 GPUs
would take about 9.5 months, and 10,000 GPUs would take 29.7 days.So, as you see, it really depends on the resources available to an
attacker. In general though, right now, a password with entropy
80 bits and upwards, from the perspective of an attacker, is pretty
much infeasible to crack (so a 5-word password from a significantly
sized source dictionary and a good quality PRNG). This will, of course,
possibly change in the age of quantum computers.DictionaryThe included dictionary is a "cleaned out" (see thewordlist cleancommand provided bypasswdgen) version of a dictionary created
throughSCOWL (And Friends), using theirword list generator.At present, the embedded dictionary contains71,188words, ensuring
an entropy oflog2(71,188) = 16.119bits per word.LegalCopyright 2000-2014 by Kevin AtkinsonPermission to use, copy, modify, distribute and sell these word
lists, the associated scripts, the output created from the scripts,
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appears in all copies and
that both that copyright notice and this permission notice appear in
supporting documentation. Kevin Atkinson makes no representations
about the suitability of this array for any purpose. It is provided
"as is" without express or implied warranty.Copyright (c) J Ross Beresford 1993-1999. All Rights Reserved.The following restriction is placed on the use of this publication:
if The UK Advanced Cryptics Dictionary is used in a software package
or redistributed in any form, the copyright notice must be
prominently displayed and the text of this document must be included
verbatim.There are no other restrictions: I would like to see the list
distributed as widely as possible.Many sources were used in the creation of SCOWL, most of them were in
the public domain or used indirectly.  For a full list please see the
SCOWL readme.http://wordlist.aspell.net/ReferencesThe following sources were consulted in building the password generator:Entropy (information theory) ~ WikipediaHow should I calculate the entropy of a password? ~ Cryptography StackExchangeHow to calculate password entropyPermutation ~ WikipediaLicenseThe MIT License (MIT)Copyright (c) 2016-2019 Thane ThomsonPermission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.