Cómo crear un generador de contraseñas seguro en Python

Actualizado el: 11/07/2026
Tempo de leitura: 4 minutos
Criptografia e segurança de dados em Python

Un generador de contraseñas es un proyecto útil para practicar strings, bucles, funciones, entrada de terminal y validación. También es una herramienta de seguridad, así que una decisión importa desde el principio: las contraseñas deben utilizar una fuente de aleatoriedad criptográficamente segura. El módulo random sirve para juegos y simulaciones, no para secretos.

En este tutorial construirás un generador de contraseñas seguro en Python con los módulos estándar secrets y string. Añadirás longitud configurable, reglas de caracteres, validación, una interfaz de terminal y pruebas. El programa genera las contraseñas localmente y no las guarda.

Por qué utilizar secrets

random es determinista y puede reproducir secuencias a partir de su estado interno. Esto es útil para pruebas, pero peligroso para contraseñas, tokens, enlaces de recuperación y claves de API. secrets utiliza la fuente segura del sistema operativo.

Generador seguro mínimo

import secrets
import string

alfabeto = (
    string.ascii_letters
    + string.digits
    + string.punctuation
)

contrasena = "".join(
    secrets.choice(alfabeto)
    for _ in range(20)
)

print(contrasena)

La guía de strings en Python explica unión, búsqueda y otros métodos utilizados para construir el resultado.

Crear una función reutilizable

import secrets
import string

def generar_contrasena(longitud=20):
    if longitud < 12:
        raise ValueError(
            "La longitud mínima es 12"
        )

    alfabeto = (
        string.ascii_letters
        + string.digits
        + string.punctuation
    )

    return "".join(
        secrets.choice(alfabeto)
        for _ in range(longitud)
    )

La función devuelve la contraseña en lugar de imprimirla. Así puede utilizarse desde una CLI, una interfaz gráfica o una aplicación web. Consulta la guía de funciones en Python para repasar parámetros y valores de retorno.

Garantizar categorías obligatorias

Algunos servicios exigen al menos una minúscula, una mayúscula, un dígito y un símbolo. Una estrategia segura es generar una candidata completa, validarla y repetir solamente cuando no cumple la política.

import secrets
import string

def cumple_politica(contrasena):
    return (
        any(c.islower() for c in contrasena)
        and any(c.isupper() for c in contrasena)
        and any(c.isdigit() for c in contrasena)
        and any(c in string.punctuation for c in contrasena)
    )

def generar_contrasena(longitud=20):
    if longitud < 12:
        raise ValueError(
            "La longitud mínima es 12"
        )

    alfabeto = (
        string.ascii_letters
        + string.digits
        + string.punctuation
    )

    while True:
        candidata = "".join(
            secrets.choice(alfabeto)
            for _ in range(longitud)
        )

        if cumple_politica(candidata):
            return candidata

El operador utilizado para buscar símbolos se explica en la guía del operador in en Python.

Elegir grupos de caracteres

import string

def crear_alfabeto(
    *,
    minusculas=True,
    mayusculas=True,
    digitos=True,
    simbolos=True,
):
    partes = []

    if minusculas:
        partes.append(string.ascii_lowercase)
    if mayusculas:
        partes.append(string.ascii_uppercase)
    if digitos:
        partes.append(string.digits)
    if simbolos:
        partes.append(string.punctuation)

    alfabeto = "".join(partes)

    if not alfabeto:
        raise ValueError(
            "Selecciona al menos un grupo"
        )

    return alfabeto

Los argumentos con nombre hacen que las llamadas sean más claras. Si reduces el tamaño del alfabeto, compensa utilizando una contraseña más larga.

Excluir caracteres ambiguos

Al escribir manualmente una contraseña, caracteres como cero y O mayúscula, o uno, l minúscula e I mayúscula, pueden confundirse.

AMBIGUOS = set("0O1lI")

def eliminar_ambiguos(alfabeto):
    return "".join(
        caracter
        for caracter in alfabeto
        if caracter not in AMBIGUOS
    )

Versión completa

import secrets
import string

AMBIGUOS = set("0O1lI")

def generar_contrasena(
    longitud=20,
    *,
    simbolos=True,
    evitar_ambiguos=False,
):
    if longitud < 12:
        raise ValueError(
            "La longitud mínima es 12"
        )

    grupos = [
        string.ascii_lowercase,
        string.ascii_uppercase,
        string.digits,
    ]

    if simbolos:
        grupos.append(string.punctuation)

    alfabeto = "".join(grupos)

    if evitar_ambiguos:
        alfabeto = "".join(
            c for c in alfabeto
            if c not in AMBIGUOS
        )

    while True:
        candidata = "".join(
            secrets.choice(alfabeto)
            for _ in range(longitud)
        )

        requisitos = [
            any(c.islower() for c in candidata),
            any(c.isupper() for c in candidata),
            any(c.isdigit() for c in candidata),
        ]

        if simbolos:
            requisitos.append(
                any(
                    c in string.punctuation
                    for c in candidata
                )
            )

        if all(requisitos):
            return candidata

Añadir una interfaz de terminal

import argparse

def crear_parser():
    parser = argparse.ArgumentParser(
        description=(
            "Genera una contraseña aleatoria segura."
        )
    )
    parser.add_argument(
        "--longitud",
        type=int,
        default=20,
        help="Longitud mínima 12",
    )
    parser.add_argument(
        "--sin-simbolos",
        action="store_true",
        help="Excluye signos de puntuación",
    )
    parser.add_argument(
        "--evitar-ambiguos",
        action="store_true",
        help="Excluye 0, O, 1, l e I",
    )
    return parser

def main():
    args = crear_parser().parse_args()

    contrasena = generar_contrasena(
        args.longitud,
        simbolos=not args.sin_simbolos,
        evitar_ambiguos=args.evitar_ambiguos,
    )

    print(contrasena)

if __name__ == "__main__":
    main()

La guía para crear una CLI con argparse explica opciones, banderas, validación y empaquetado.

Crear passphrases

Una passphrase combina palabras elegidas aleatoriamente. Puede ser más fácil de escribir, pero la seguridad depende del tamaño de la lista, la cantidad de palabras y la selección independiente.

import secrets

PALABRAS_DEMO = [
    "ancla", "bambu", "cobre", "delfin",
    "estrella", "bosque", "galaxia", "puerto",
    "isla", "jardin", "kernel", "linterna",
]

def passphrase_demo(cantidad=5):
    if cantidad < 4:
        raise ValueError(
            "Utiliza al menos cuatro palabras"
        )

    return "-".join(
        secrets.choice(PALABRAS_DEMO)
        for _ in range(cantidad)
    )

Esta lista pequeña es solamente una demostración de programación. Una herramienta real necesita una lista amplia y revisada.

Generar no es almacenar

Un sistema de autenticación no debe guardar contraseñas recuperables en texto plano, logs o archivos de configuración. Debe almacenar un hash creado por un algoritmo específico para contraseñas y una sal única. No diseñes tu propio sistema criptográfico.

Probar las reglas

import string

def test_contrasena_predeterminada():
    contrasena = generar_contrasena()

    assert len(contrasena) == 20
    assert any(c.islower() for c in contrasena)
    assert any(c.isupper() for c in contrasena)
    assert any(c.isdigit() for c in contrasena)
    assert any(
        c in string.punctuation
        for c in contrasena
    )

Las pruebas deben verificar reglas, no predecir una salida aleatoria. Consulta la guía de Pytest para principiantes.

Utilizar un entorno virtual

Este proyecto usa solamente la biblioteca estándar, pero un entorno aislado sigue siendo útil cuando añades una interfaz o herramientas de prueba. La guía de entornos virtuales en Python explica el flujo recomendado.

Errores frecuentes

  • Usar random.choice() para contraseñas o tokens.
  • Confiar en una contraseña corta solo porque contiene símbolos.
  • Guardar o registrar automáticamente el resultado.
  • Construir un patrón predecible con posiciones fijas.
  • Usar una lista mínima para una passphrase real.
  • Confundir generación con hashing seguro.

Conclusión

Un generador de contraseñas seguro en Python es pequeño porque la biblioteca estándar proporciona la fuente de aleatoriedad adecuada. Utiliza secrets, elige una longitud generosa, valida la política, evita guardar la salida y trata el hashing como una responsabilidad separada.

Documentación y seguridad

Consulta la documentación oficial de Python sobre el módulo secrets. Para el almacenamiento de credenciales, revisa la guía de almacenamiento de contraseñas de OWASP.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Jogo da forca para iniciantes desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un juego del ahorcado en Python

    Crea un juego del ahorcado en Python con palabras aleatorias, validación, letras repetidas, vidas, dibujos ASCII, pistas y opción de

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Quiz interativo no terminal desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un quiz en Python para la terminal

    Crea un quiz en Python para la terminal con preguntas, validación, puntuación, respuestas mezcladas, repetición, JSON y pruebas.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Jogo de adivinhação de números desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Juego de adivinar números en Python

    Crea un juego de adivinar números en Python con niveles, pistas, intentos limitados, validación, repetición y funciones fáciles de probar.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Desenhos para iniciantes usando Turtle em Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Dibujar con Turtle en Python: guía completa

    Aprende a dibujar con Turtle en Python: movimientos, figuras, colores, eventos del teclado y un proyecto interactivo completo.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026