Immer wieder braucht man Passwörter. Für eine Webseite, einen Dienst, was auch immer. Man sollte es ja tunlichst vermeiden, ein Passwort mehrfach zu benutzen. Wird ein Account gehackt bei einem Anbieter, sind gleich Dutzende andere weg, Sie kennen das.
Und als Entwickler benötigt man für seine Anwendungen außerdem API-Keys, für die es spezifischere Anforderungen gibt, weil sie sich für Weitergabe in einer URL und die Befehlszeile eignen müssen.
Sich immer wieder neue Passwörter und API-Keys selbst ausdenken zu müssen, ist mühsam. Und auch nicht ungefährlich, aus Security-Sicht. Denn als Mensch hat man es sehr schwer, echte Zufallspasswörter und damit hohe Entropie zu erzeugen.
Natürlich, es gibt zumindest in Linux das eine oder andere Standard-Werkzeug, das man für die Erzeugung von Passwörtern verwenden kann. openssl, oder cat /dev/urandom mit Filter für alphanumerische Zeichen. Und natürlich ist das eine oder andere Tool verfügbar.
Wir fügen heute ein weiteres solches Tool für Sie hinzu und stellen es unter die Apache 2.0 Lizenz. Sie dürfen es frei verwenden, modifizieren und weitergeben – auch kommerziell. Wir nennen unser Tool genpwd und es ist eine Python-Anwendung.
genpwd.py hat einige besondere Eigenschaften: Natürlich sind die von ihm erzeugten Passwörter streng zufällig, aber es garantiert außerdem mindestens einen Kleinbuchstaben, einen Großbuchstaben, eine Ziffer, und ein Sonderzeichen. Denn das wird mittlerweile von vielen Plattformen erzwungen, dass ein Passwort diese Bedingungen erfüllt.
Die Bedingung „mindestens ein Sonderzeichen“ kann man in unserem Programm aber abschalten, denn für API-Keys sind Sonderzeichen eher ungeeignet, weil sie in einer URL oder auf der Command Line ein Durcheinander anrichten können.
Die Zeichen „0O1lI“ (Null, Groß O, Ziffer 1, Klein L, Groß I) werden von genpwd.py immer ausgeblendet, weil sie zu leicht verwechselbar sind, und sich aus diesem Grund für Passwörter nicht eignen. Man soll sie schließlich auch eingeben können, falls man gerade keinen Passwort-Manager zur Hand hat.
Außerdem können Sie sich mit unserem Tool die Entropie eines Passworts anzeigen lassen. Es ist ja nicht möglich, den gesamten Zeichensatz von von 0 – 255 zu verwenden in einem Passwort, deshalb ist die Entropie eines Passworts immer geringer als die Anzahl der Bits in seinen Zeichen.
Die Entropie eines Passworts ist ein äußerst interessanter Wert. Derzeit gelten Passwörter mit 128 Bit als sicher. Aber wussten Sie, dass ein zufälliges Passwort mit 16 Zeichen (= 128 Bit) nur etwa 88 Bit Entropie hat? Weil eben der Zeichensatz, aus dem es generiert wurde, nicht der vollständige Zeichensatz ist. Tatsächlich braucht man Passwörter mit einer Länge von mind. 23 Zeichen, um eine Entropie größer 128 zu erreichen. Und sich 23 wirklich zufällige Zeichen auszudenken, das fällt Menschen durchaus schwer.
Schließlich, das Passwort muss in den Browser bzw. in eine Anwendung. Deshalb kann genpwd.py es in das Clipboard kopieren, damit Sie das Passwort gleich weiterverarbeiten können.
Und unsere Anwendung ist Cross-Plattform, sie läuft auf jedem Betriebssystem, das einen Python3 Interpreter installiert hat. Python gibt es für Linux, Windows, MacOS und weitere Betriebssysteme.
Genug der Vorrede, hier ist die Usage von genpwd.py:
usage: genpwd.py [-h] [-s] [-n] [-b] [-v] [length] Generate a random password of a given length. positional arguments: length password length (default: 16, max: 2048) options: -h, --help show this help message and exit -s, --no-special exclude special characters from the password -n, --no-clipboard do not copy the password to the clipboard -b, --verbose show estimated password entropy in bits -v, --version show program's version number and exit Examples: python genpwd.py 12 # Generate a 12-character password python genpwd.py # Generate a default length password python genpwd.py 12 --no-special # Generate without special characters python genpwd.py 16 --no-clipboard # Print password without copying python genpwd.py 20 --verbose # Show estimated entropy in bits
Und hier folgt der Code unserer Open Source Anwendung. Sie können ihn sich entweder aus dem Browser herauskopieren, oder Sie laden ein von uns für Sie vorbereitetes ZIP.
#!/usr/bin/env python3
import argparse, math, secrets, string, sys
try:
import pyperclip
except ModuleNotFoundError:
pyperclip = None
DEFAULT_LENGTH = 16
VERSION = "1.0.0"
MAX_LENGTH = 2048
ALLOWED_SPECIAL = "!@#$%*()_-" # may not be empty
AMBIGUOUS_CHARS = set("0O1lI")
UPPERCASE_LETTERS = "".join(char for char in string.ascii_uppercase if char not in AMBIGUOUS_CHARS)
LOWERCASE_LETTERS = "".join(char for char in string.ascii_lowercase if char not in AMBIGUOUS_CHARS)
DIGITS = "".join(char for char in string.digits if char not in AMBIGUOUS_CHARS)
def get_charset(include_special: bool = True) -> str:
"""
Get the full character set based on whether specials are included.
Args:
include_special: Whether special characters are allowed.
Returns:
The combined character set string.
"""
allowed_special = ALLOWED_SPECIAL if include_special else ""
return UPPERCASE_LETTERS + LOWERCASE_LETTERS + DIGITS + allowed_special
def estimate_entropy_bits(length: int, include_special: bool = True) -> float:
"""
Estimate password entropy in bits based on the actual generation algorithm.
The calculation accounts for the guaranteed character requirements:
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- At least one special character (if include_special=True)
- Remaining positions filled from full charset
Args:
length: Desired password length.
include_special: Whether special characters are allowed.
Returns:
Estimated entropy in bits.
"""
minimum_length = 4 if include_special else 3
if length < minimum_length: raise ValueError(f"length must be at least {minimum_length}") charset = get_charset(include_special=include_special) charset_size = len(charset) # Entropy from guaranteed characters (constrained to subsets) entropy = math.log2(len(UPPERCASE_LETTERS)) entropy += math.log2(len(LOWERCASE_LETTERS)) entropy += math.log2(len(DIGITS)) if include_special: entropy += math.log2(len(ALLOWED_SPECIAL)) guaranteed_count = 4 else: guaranteed_count = 3 # Entropy from remaining positions (full charset) remaining = length - guaranteed_count entropy += remaining * math.log2(charset_size) return entropy def generate_password(length: int, include_special: bool = True) -> str:
"""
Generate a random password of the specified length.
Args:
length: Desired password length (must be >= 4 with specials, >= 3 without,
and <= MAX_LENGTH).
include_special: Whether to include special characters in the password.
Returns:
A random password string.
Raises:
ValueError: If length is outside the valid range (minimum or maximum).
"""
minimum_length = 4 if include_special else 3
if length < minimum_length: raise ValueError(f"length must be at least {minimum_length}") if length > MAX_LENGTH:
raise ValueError(f"length must not exceed {MAX_LENGTH}")
all_chars = get_charset(include_special=include_special)
password_chars = [
secrets.choice(UPPERCASE_LETTERS),
secrets.choice(LOWERCASE_LETTERS),
secrets.choice(DIGITS),
]
if include_special:
password_chars.append(secrets.choice(ALLOWED_SPECIAL))
remaining_length = length - len(password_chars)
password_chars.extend([secrets.choice(all_chars) for _ in range(remaining_length)])
secrets.SystemRandom().shuffle(password_chars)
return "".join(password_chars)
def main() -> None:
parser = argparse.ArgumentParser(
description="Generate a random password of a given length.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python genpwd.py 12 # Generate a 12-character password
python genpwd.py # Generate a default length password
python genpwd.py 12 --no-special # Generate without special characters
python genpwd.py 16 --no-clipboard # Print password without copying
python genpwd.py 20 --verbose # Show estimated entropy in bits
""",
)
parser.add_argument(
"length",
type=int,
nargs="?",
default=DEFAULT_LENGTH,
help=f"password length (default: {DEFAULT_LENGTH}, max: {MAX_LENGTH})",
)
parser.add_argument(
"-s",
"--no-special",
action="store_true",
dest="no_special",
help="exclude special characters from the password",
)
parser.add_argument(
"-n",
"--no-clipboard",
action="store_true",
help="do not copy the password to the clipboard",
)
parser.add_argument(
"-b",
"--verbose",
action="store_true",
help="show estimated password entropy in bits",
)
parser.add_argument("-v", "--version", action="version", version=f"%(prog)s {VERSION}")
args = parser.parse_args()
try:
password = generate_password(args.length, include_special=not args.no_special)
except ValueError as exc:
print(f"Error: {exc}", file=sys.stderr)
sys.exit(1)
if not args.no_clipboard:
if pyperclip is None:
print(
"pyperclip not installed; copy skipped (--no-clipboard to suppress this message)",
file=sys.stderr,
)
else:
try:
pyperclip.copy(password)
except Exception:
print("Could not copy to clipboard", file=sys.stderr)
if args.verbose:
entropy_bits = estimate_entropy_bits(args.length, include_special=not args.no_special)
print(f"Estimated entropy: {entropy_bits:.2f} bits", file=sys.stderr)
print(password)
if __name__ == "__main__":
main()
Das Programm ist vollständig portabel für alle Betriebssysteme, für die es einen Python-Interpreter gibt, aber für die Funktion „Copy to Clipboard“ gibt es eine externe Abhängigkeit. Sie müssen dafür die Bibliothek pyperclip installieren. Das Programm arbeitet einwandfrei auch ohne diese Abhängigkeit, kann dann aber nicht in das Clipboard kopieren. Hier einige Tipps, wie die Installation von pyperclip in diversen Betriebssystemen möglich ist:
Mit dem Python-Paketmanager ist die Installation auf allen Plattformen identisch. Verwenden Sie pip install pyperclip um Ihrem Python die Bibliothek hinzuzufügen. Unter Linux müssen Sie außerdem xclip bzw. das für Ihre Distribution passende Paket aus dem Repository installieren.
Oder Sie verwenden aus dem Repository python3-pyperclip, also sudo dnf install python3-pyperclip oder sudo apt install python3-pyperclip und so weiter.
Jedoch, wie gesagt, die Anwendung funktioniert einwandfrei auch ohne pyperclip. Dann muss man eben mit der Maus markieren und selbst ins Clipboard einfügen. Etwas, das aber zumindest mir immer gewaltig auf die Nerven geht. Mist, ein Zeichen zu wenig erwischt, und gleich nochmal mit der Maus fummeln. Es ist schon wirklich praktisch, wenn ein neu erzeugtes Passwort gleich im Clipboard ist, die kleine Mühe der Installation einer externen Bibliothek lohnt sich also sehr, meiner Meinung.















