Ob API-Token, temporaere Passwoerter oder Einmal-Codes – in der Praxis braucht man haeufig zufaellige Zeichenketten. Python bringt alles mit, was du dafuer brauchst: kein pip install noetig. Dieser Artikel zeigt dir zehn Muster, von einfach bis fortgeschritten.
Hinweis: Fuer sicherheitsrelevante Anwendungen solltest du immer das secrets-Modul verwenden. random ist nicht kryptografisch sicher.
1. secrets.token_urlsafe – Der Allrounder
Die einfachste und sicherste Methode fuer Tokens. Das Ergebnis ist Base64-URL-kodiert und eignet sich perfekt fuer URLs und APIs:
import secrets
token = secrets.token_urlsafe(32)
print(token) # z.B. 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1c...'
Der Parameter gibt die Anzahl der Bytes an. 32 Bytes ergeben etwa 43 Zeichen nach der Base64-Kodierung. Fuer die meisten Zwecke ist das mehr als ausreichend.
2. secrets.token_hex – Hexadezimale Tokens
Wenn du nur Hex-Zeichen brauchst (0-9, a-f), ist token_hex die richtige Wahl:
import secrets
hex_token = secrets.token_hex(16)
print(hex_token) # z.B. 'a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5'
print(len(hex_token)) # 32 Zeichen (2 Hex-Zeichen pro Byte)
3. secrets.choice – Passwort aus Zeichenpool
Fuer klassische Passwoerter mit bestimmten Zeichenklassen kombinierst du secrets.choice mit string-Konstanten:
import secrets
import string
def generate_password(length=16):
alphabet = string.ascii_letters + string.digits + string.punctuation
return "".join(secrets.choice(alphabet) for _ in range(length))
print(generate_password()) # z.B. 'k#9Lm!xQ2@pW7&rT'
print(generate_password(24)) # 24 Zeichen
Mit string.ascii_letters erhaeltst du Gross- und Kleinbuchstaben, string.digits liefert Ziffern und string.punctuation die Sonderzeichen.
4. Passwort mit Mindestanforderungen
Viele Systeme verlangen mindestens einen Grossbuchstaben, eine Ziffer und ein Sonderzeichen. So stellst du das sicher:
import secrets
import string
def strong_password(length=16):
if length < 4:
raise ValueError("Mindestlaenge ist 4")
alphabet = string.ascii_letters + string.digits + string.punctuation
while True:
pw = "".join(secrets.choice(alphabet) for _ in range(length))
if (any(c.islower() for c in pw)
and any(c.isupper() for c in pw)
and any(c.isdigit() for c in pw)
and any(c in string.punctuation for c in pw)):
return pw
print(strong_password())
Die while True-Schleife generiert so lange neue Passwoerter, bis alle Anforderungen erfuellt sind. Bei 16 Zeichen klappt das fast immer im ersten Versuch.
5. Passphrase im Diceware-Stil
Passphrases sind laenger, aber leichter zu merken. Hier ein Beispiel mit einer eigenen Wortliste:
import secrets
WOERTER = [
"apfel", "birne", "kirsche", "dattel", "feige",
"traube", "kiwi", "mango", "orange", "pflaume",
"wolke", "berg", "fluss", "stein", "blatt",
"stern", "mond", "sonne", "regen", "wind",
]
def passphrase(wort_anzahl=4, trennzeichen="-"):
return trennzeichen.join(
secrets.choice(WOERTER) for _ in range(wort_anzahl)
)
print(passphrase()) # z.B. 'berg-mango-stern-regen'
print(passphrase(6, ".")) # z.B. 'kiwi.blatt.sonne.wind.birne.stein'
In der Praxis wuerdest du eine groessere Wortliste verwenden (z.B. die EFF-Wortliste mit 7776 Eintraegen). Je groesser die Liste, desto mehr Entropie pro Wort.
6. os.urandom – Rohe Zufallsbytes
Wenn du rohe Bytes brauchst (z.B. fuer Verschluesselung), ist os.urandom die niedrigste Ebene:
import os
import base64
raw = os.urandom(32)
print(raw.hex()) # Hex-Darstellung
print(base64.b64encode(raw).decode()) # Base64-Darstellung
# Nur ASCII-Buchstaben und Ziffern
token = base64.b32encode(os.urandom(20)).decode().rstrip("=")
print(token) # z.B. 'JBSWY3DPEHPK3PXP4GQRGZMB3FQWI'
os.urandom liest direkt vom Betriebssystem-Zufallsgenerator (/dev/urandom auf Linux). Das secrets-Modul nutzt intern dieselbe Quelle.
7. uuid.uuid4 – Einmalige Bezeichner
UUIDs sind keine Passwoerter im klassischen Sinn, aber hervorragend als eindeutige Bezeichner geeignet:
import uuid
u = uuid.uuid4()
print(u) # z.B. 'a3f2b8c1-d4e5-4f6a-b8c9-d0e1f2a3b4c5'
print(u.hex) # ohne Bindestriche: 'a3f2b8c1d4e54f6ab8c9d0e1f2a3b4c5'
# Als kurzer Token
short = u.hex[:12]
print(short) # z.B. 'a3f2b8c1d4e5'
UUID4 basiert auf Zufallszahlen und bietet 122 Bit Entropie. Die Wahrscheinlichkeit einer Kollision ist astronomisch gering.
8. hashlib – Deterministische Tokens
Manchmal brauchst du einen Token, der sich aus einer Eingabe reproduzierbar ableiten laesst:
import hashlib
import time
def make_token(user_id, secret_key):
ts = str(int(time.time()))
raw = f"{user_id}:{ts}:{secret_key}"
return hashlib.sha256(raw.encode()).hexdigest()[:32], ts
token, timestamp = make_token("user42", "mein-geheimer-schluessel")
print(f"Token: {token}")
print(f"Erstellt: {timestamp}")
Achtung: Solche Tokens sind nur so sicher wie der secret_key. Fuer echte HMAC-basierte Tokens verwende das hmac-Modul.
9. hmac – Signierte Tokens
Mit HMAC kannst du Tokens erstellen, deren Echtheit du spaeter verifizieren kannst:
import hmac
import hashlib
import time
SECRET = b"super-geheimer-schluessel"
def create_signed_token(data):
ts = str(int(time.time()))
msg = f"{data}:{ts}".encode()
sig = hmac.new(SECRET, msg, hashlib.sha256).hexdigest()
return f"{data}:{ts}:{sig}"
def verify_token(token):
parts = token.rsplit(":", 2)
if len(parts) != 3:
return False
data, ts, sig = parts
msg = f"{data}:{ts}".encode()
expected = hmac.new(SECRET, msg, hashlib.sha256).hexdigest()
return hmac.compare_digest(sig, expected)
token = create_signed_token("user42")
print(token)
print(verify_token(token)) # True
hmac.compare_digest verhindert Timing-Angriffe beim Vergleich. Verwende diese Funktion immer statt dem normalen ==-Operator.
10. random – Nur fuer nicht-sicherheitsrelevante Zwecke
Warnung: Das random-Modul verwendet den Mersenne-Twister-Algorithmus, der vorhersagbar ist. Verwende es niemals fuer Passwoerter, Tokens oder Sicherheitsfunktionen.
import random
import string
# NUR fuer Tests, Demos oder Spiele!
def demo_password(length=12):
chars = string.ascii_letters + string.digits
return "".join(random.choices(chars, k=length))
print(demo_password())
# Reproduzierbar mit Seed (nützlich fuer Tests)
random.seed(42)
print(demo_password()) # immer dasselbe Ergebnis
Der einzige legitime Einsatz: Test-Fixtures, wo du reproduzierbare Zufallsdaten brauchst. In Produktion immer secrets nehmen.
Zusammenfassung
Hier ein schneller Ueberblick, welche Methode wofuer geeignet ist:
Sicher (kryptografisch): secrets.token_urlsafe, secrets.token_hex, secrets.choice, os.urandom, hmac
Eindeutig (aber kein Passwort): uuid.uuid4, hashlib
Unsicher (nur Tests): random
Fuer die allermeisten Faelle ist secrets.token_urlsafe(32) die beste Wahl. Einfach, sicher und sofort einsatzbereit.

Schreibe einen Kommentar