passwd-gen: Generate Secure Passwords with a Simple Python CLI
Creating passwords manually is tedious and error-prone. Many online generators leak; many built-in tools use Math.random() which isn't cryptographically secure. I built passwd-gen — a lightweight Python CLI that generates truly random passwords using only standard library modules.
What It Does
The tool creates cryptographically secure random passwords:
- Configurable length — 8 to 64+ characters (default 16)
- Character sets — Lowercase + uppercase + digits + special chars by default
-
Secure source —
secrets.token_hex()draws from OS entropy - No dependencies — Works anywhere Python runs
Why Build This?
- Existing generators often rely on non-secure
randommodule (vulnerable to prediction) - Web services may store cookies, log data, or expose through browser fingerprinting
- Need a simple offline tool that generates strong passwords without internet
- Clean output for scripting in shell pipelines
Installation
Zero pip install needed. Just copy the script:
cp passwd_gen.py ~/bin/
chmod +x ~/bin/passwd_gen.py
# Then anytime:
passwd_gen.py
Or move it into a project directory and add to scripts folder.
Usage Examples
Generate one password (length 16)
python passwd_gen.py
# Output: xK9#mP2@vL$qZw7R
Generate multiple passwords
python passwd_gen.py -c 5
# Outputs 5 lines with passwords:
# aB8#xL2@pN$qR5tY
# 3fG#hJ9@kL$mP6wQ
# ...
Longer passwords (for modern standards)
NIST recommends 128 bits = ~15 chars minimum. Modern sites want longer:
python passwd_gen.py -l 32
# Output: 7xK2@m!p9$vL4#nQ8$jR3@wP6&uA
Write to file for batch use
python passwd_gen.py -c 10 -o ~/passbook.txt
cat passbook.txt
This creates a local list you can copy passwords from manually.
Silent mode for scripts
When piping password output into another script, avoid "Generated X password(s):" text:
python passwd_gen.py -q -c 3 | grep -v '^$' >> app.log
Command Line Options
-
-c, --count N— Number of passwords to generate (default 1) -
-l, --length N— Password length in characters (default 16) -
-o, --output FILE— Write passwords to file instead of stdout -
-q, --quiet— Silent mode: pure password output
The Code in Brief
The core generator is a ~30-line function using secrets:
import secrets, hashlib
def generate_password(length=16):
chars = "abc...XYZ0123456789!@#$%^&*()-_=+[]{};:'<>,.?/"
def rand_pick(n):
"""Random index using secrets."""
raw = int(secrets.token_hex(16)[:len(hex(n))], 16) % n
return raw
result = [chars[rand_pick(len(chars))] for _ in range(length)]
# Shuffle to avoid patterns (vowels clustered, etc.)
def shuffle(items):
import random # Using secrets internally but standard shuffle helper
for i in range(len(items)-1, 0, -1):
j = rand_pick(i+1)
items[i], items[j] = items[j], items[i]
shuffle(result)
return ''.join(result)
The secrets.token_hex() call provides ~2x the random bits needed for one character index; any remainder from that is discarded — cryptographic security over speed.
SHA256 hashing (included in full version) lets you store hashes of passwords when verifying against user-entered values, though this feature exists mostly for advanced scripting use cases.
Comparison: Why Not Just Use System Password Generator?
Most Linux systems offer gpg --gen-key or similar — but those create keys, not passwords to copy/use across sites. Websites expect printable ASCII characters (not binary blobs). Browser-based generators can leak via XSS, clipboard monitoring, or browser fingerprinting in tracking scenarios. Offline is simpler and more portable.
Security Notes
- Uses
secrets, NOTrandom, for random selection - No timing attacks possible outside the OS — uses
/dev/urandom(Linux) orCryptGenRandom(Windows) - Passwords printed to stdout; avoid redirecting sensitive lists into untrusted processes
- The tool doesn't store passwords anywhere after generation
Top comments (0)