Claude Code for secrets: Python Cryptographic Token Generator — Claude Skills 360 Blog
Blog / AI / Claude Code for secrets: Python Cryptographic Token Generator
AI

Claude Code for secrets: Python Cryptographic Token Generator

Published: November 24, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s secrets module generates cryptographically secure random values backed by the OS CSPRNG (os.urandom), suitable for tokens, API keys, and passwords. import secrets. Bytes: secrets.token_bytes(nbytes=32) → raw bytes. Hex: secrets.token_hex(nbytes=32)str of 2*nbytes hex digits. URL-safe: secrets.token_urlsafe(nbytes=32) → URL-safe base64 (no +//) of approximately nbytes * 4/3 characters. Random selection: secrets.choice(seq) → one element; secrets.randbelow(n)int in [0, n); secrets.randbits(k)int with k random bits. Class: secrets.SystemRandom() — a random.Random subclass wired to the OS CSPRNG; useful when you need shuffle, sample, or uniform from existing random-API code. Size guidance: 32 bytes (256 bits) for session tokens, API keys, and CSRF tokens; 16 bytes (128 bits) minimum viable; 6 bytes for short-lived OTP; always at least ceil(desired_bits / 8) bytes. Comparison: use hmac.compare_digest(a, b) for timing-safe equality — do not use ==. Claude Code generates API key generators, session token systems, password reset flows, OTP generators, and secure nonce producers.

CLAUDE.md for secrets

## secrets Stack
- Stdlib: import secrets
- Token:  secrets.token_bytes(32)        # 32 raw bytes
-         secrets.token_hex(32)          # 64-char hex string
-         secrets.token_urlsafe(32)      # URL-safe base64, ~43 chars
- Pick:   secrets.choice(alphabet)       # single secure random element
- Int:    secrets.randbelow(1_000_000)   # [0, n)
- Note:   Never use random module for security-sensitive values
-         Always use hmac.compare_digest() to compare tokens

secrets Cryptographic Token Pipeline

# app/secretsutil.py — tokens, API keys, passwords, OTP, CSRF, nonces
from __future__ import annotations

import hashlib
import hmac
import math
import secrets
import string
import time
from dataclasses import dataclass


# ─────────────────────────────────────────────────────────────────────────────
# 1. Token generators
# ─────────────────────────────────────────────────────────────────────────────

def token(nbytes: int = 32) -> str:
    """
    Generate a URL-safe cryptographic token of nbytes entropy.
    Safe for session IDs, password reset links, and CSRF tokens.

    Example:
        tok = token()           # 43-character URL-safe token
        tok = token(16)         # ~22 chars (128-bit security)
    """
    return secrets.token_urlsafe(nbytes)


def token_hex(nbytes: int = 32) -> str:
    """
    Generate a hex-encoded cryptographic token.

    Example:
        key = token_hex(32)     # 64 hex chars, 256-bit security
    """
    return secrets.token_hex(nbytes)


def api_key(prefix: str = "", nbytes: int = 32) -> str:
    """
    Generate a prefixed API key (e.g., "sk_live_abc123...").

    Example:
        key = api_key("sk_live")   # "sk_live_<64hex>"
        key = api_key("tok")       # "tok_<64hex>"
    """
    raw = secrets.token_hex(nbytes)
    return f"{prefix}_{raw}" if prefix else raw


# ─────────────────────────────────────────────────────────────────────────────
# 2. Password and passphrase generators
# ─────────────────────────────────────────────────────────────────────────────

_LOWER  = string.ascii_lowercase
_UPPER  = string.ascii_uppercase
_DIGITS = string.digits
_PUNCT  = "!@#$%^&*()-_=+[]{}|;:,.<>?"
_SAFE_PUNCT = "!@#$%^&*-_+."


def random_password(
    length: int = 16,
    use_lower: bool = True,
    use_upper: bool = True,
    use_digits: bool = True,
    use_punct: bool = True,
) -> str:
    """
    Generate a cryptographically secure random password.
    Guarantees at least one character from each enabled class.

    Example:
        pw = random_password(20)
        pw = random_password(12, use_punct=False)
    """
    alphabet = ""
    required = []
    if use_lower:
        alphabet += _LOWER
        required.append(secrets.choice(_LOWER))
    if use_upper:
        alphabet += _UPPER
        required.append(secrets.choice(_UPPER))
    if use_digits:
        alphabet += _DIGITS
        required.append(secrets.choice(_DIGITS))
    if use_punct:
        alphabet += _SAFE_PUNCT
        required.append(secrets.choice(_SAFE_PUNCT))

    if not alphabet:
        raise ValueError("At least one character class must be enabled")

    extra = [secrets.choice(alphabet) for _ in range(length - len(required))]
    chars = required + extra
    # Shuffle to avoid required chars always appearing first
    for i in range(len(chars) - 1, 0, -1):
        j = secrets.randbelow(i + 1)
        chars[i], chars[j] = chars[j], chars[i]
    return "".join(chars)


def passphrase(
    word_count: int = 4,
    wordlist: list[str] | None = None,
    separator: str = "-",
) -> str:
    """
    Generate a diceware-style passphrase from a wordlist.
    If wordlist is None, uses a built-in 100-word mini-list.

    Example:
        phrase = passphrase(5)
        # "coral-mighty-lamp-stone-river"
    """
    if wordlist is None:
        wordlist = [
            "alpha","brave","cloud","delta","eagle","flame","grace","house",
            "index","joker","kings","laser","micro","noble","ocean","prism",
            "quest","rover","stone","trust","ultra","valor","whale","xenon",
            "yield","zebra","amber","bloom","coral","drift","ember","frost",
            "gloom","haven","ivory","jewel","karma","lemon","maple","nexus",
            "orbit","plaza","quart","racer","solar","trail","umbra","vivid",
            "warmth","exact","youth","azure","blaze","craft","dusty","epoch",
            "field","grove","haste","ilk","jumpy","knave","lingo","marble",
            "north","owl","paint","quota","realm","slope","torch","under",
            "vault","wrist","oxen","yacht","zeal","ample","boxer","clamp",
            "dingo","envy","flare","groan","horse","ingot","jolly","kite",
            "lyric","might","nerve","optic","pivot","quirk","rivet","skate",
            "tutor","unbox","visor","wager","xerox","yolk","zippy",
        ]
    return separator.join(secrets.choice(wordlist) for _ in range(word_count))


# ─────────────────────────────────────────────────────────────────────────────
# 3. OTP and CSRF tokens
# ─────────────────────────────────────────────────────────────────────────────

def numeric_otp(digits: int = 6) -> str:
    """
    Generate a cryptographically secure numeric OTP.

    Example:
        code = numeric_otp(6)   # "827461"
    """
    upper = 10 ** digits
    return str(secrets.randbelow(upper)).zfill(digits)


def alphanumeric_otp(length: int = 8) -> str:
    """
    Generate an alphanumeric OTP (uppercase + digits, no ambiguous chars).

    Example:
        code = alphanumeric_otp(8)   # "A3K9MX2T"
    """
    alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"  # no 0/O, 1/I
    return "".join(secrets.choice(alphabet) for _ in range(length))


@dataclass
class CsrfToken:
    value:   str
    created: float

    def is_valid(self, submitted: str, max_age: float = 3600) -> bool:
        """Verify CSRF token matches and has not expired."""
        if time.time() - self.created > max_age:
            return False
        return hmac.compare_digest(self.value, submitted)

    def __str__(self) -> str:
        return self.value


def new_csrf_token() -> CsrfToken:
    """
    Generate a new CSRF token for embedding in forms.

    Example:
        csrf = new_csrf_token()
        # In form: <input type="hidden" name="csrf" value="{csrf}">
        # On submit: if not csrf.is_valid(request.form["csrf"]): abort(403)
    """
    return CsrfToken(value=secrets.token_urlsafe(32), created=time.time())


# ─────────────────────────────────────────────────────────────────────────────
# 4. Secure nonce and key derivation helpers
# ─────────────────────────────────────────────────────────────────────────────

def nonce(nbytes: int = 12) -> bytes:
    """
    Generate a cryptographic nonce (number used once) as raw bytes.
    12 bytes is standard for AES-GCM; 24 bytes for XSalsa20.

    Example:
        iv = nonce(12)   # for AES-GCM
    """
    return secrets.token_bytes(nbytes)


def entropy_bits(token_str: str, encoding: str = "urlsafe_b64") -> float:
    """
    Estimate the entropy of a token string in bits.

    Example:
        tok = secrets.token_urlsafe(32)
        print(entropy_bits(tok))   # ~256.0
    """
    if encoding == "urlsafe_b64":
        # URL-safe base64: 6 bits per char
        return len(token_str) * 6
    elif encoding == "hex":
        return len(token_str) * 4
    elif encoding == "raw":
        return len(token_str) * 8
    return 0.0


def secure_compare(a: str | bytes, b: str | bytes) -> bool:
    """
    Constant-time comparison of two strings or byte strings.
    Wraps hmac.compare_digest with input normalization.

    Example:
        if not secure_compare(token_from_db, token_from_request):
            raise PermissionError("Invalid token")
    """
    if isinstance(a, str) and isinstance(b, str):
        return hmac.compare_digest(a, b)
    if isinstance(a, bytes) and isinstance(b, bytes):
        return hmac.compare_digest(a, b)
    # Length-equalise type to prevent short-circuit
    a_bytes = a.encode() if isinstance(a, str) else a
    b_bytes = b.encode() if isinstance(b, str) else b
    return hmac.compare_digest(a_bytes, b_bytes)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== secrets demo ===")

    # ── tokens ────────────────────────────────────────────────────────────────
    print("\n--- tokens ---")
    print(f"  token(32):         {token(32)}")
    print(f"  token_hex(16):     {token_hex(16)}")
    print(f"  api_key('sk_live'):{api_key('sk_live')[:40]}...")

    # ── passwords ─────────────────────────────────────────────────────────────
    print("\n--- passwords ---")
    for _ in range(3):
        pw = random_password(16)
        bits = entropy_bits(pw, "raw")
        print(f"  {pw!r}  (≥{bits:.0f} bits)")

    print("\n--- passphrase ---")
    for _ in range(3):
        print(f"  {passphrase(4)}")

    # ── OTP ───────────────────────────────────────────────────────────────────
    print("\n--- OTP ---")
    print(f"  numeric_otp(6):      {numeric_otp(6)}")
    print(f"  alphanumeric_otp(8): {alphanumeric_otp(8)}")

    # ── CSRF ──────────────────────────────────────────────────────────────────
    print("\n--- CSRF token ---")
    csrf = new_csrf_token()
    print(f"  token: {csrf}")
    print(f"  valid (correct):   {csrf.is_valid(csrf.value)}")
    print(f"  valid (incorrect): {csrf.is_valid('tampered')}")

    # ── nonce + entropy ───────────────────────────────────────────────────────
    print("\n--- nonce + entropy ---")
    iv = nonce(12)
    print(f"  nonce(12): {iv.hex()}")
    tok = token(32)
    print(f"  entropy_bits(token(32)): ~{entropy_bits(tok):.0f} bits")

    # ── secure_compare ────────────────────────────────────────────────────────
    print("\n--- secure_compare ---")
    a = token(32)
    print(f"  secure_compare(a, a): {secure_compare(a, a)}")
    print(f"  secure_compare(a, b): {secure_compare(a, token(32))}")

    print("\n=== done ===")

For the random module alternative — random.random(), random.randint(), random.choice() — these use a Mersenne Twister PRNG that is fast and reproducible (seeded) but cryptographically insecure: past outputs can be predicted from observed outputs — never use random for passwords, tokens, session IDs, CSRF tokens, cryptographic nonces, or any security-sensitive value; use secrets for all of those and random only for simulations, games, sampling, and shuffle operations where predictability is acceptable or desired. For the os.urandom alternative — os.urandom(n) returns n cryptographically random bytes directly from the OS CSPRNG — secrets is a high-level wrapper around os.urandom that adds convenient formatting (token_hex, token_urlsafe), range-limited integers (randbelow), and sequence selection (choice); use secrets unless you specifically need raw bytes for a custom encoding or key derivation function where os.urandom is the cleaner call. The Claude Skills 360 bundle includes secrets skill sets covering token()/token_hex()/api_key() token generators, random_password()/passphrase() credential generators, numeric_otp()/alphanumeric_otp()/CsrfToken with new_csrf_token(), and nonce()/entropy_bits()/secure_compare() utilities. Start with the free tier to try cryptographic token patterns and secrets pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free