Construí un Gestor de Contraseñas Avanzado en Julia (oh si, Juliaaaa)

Published: (November 30, 2025 at 01:54 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Escribo herramientas para no hacer las cosas aburridas dos veces, y últimamente lo he estado haciendo en lenguajes que nadie espera. Esta vez: Julia. Sí, ese lenguaje científico que todos asocian con matemáticas y machine learning. Si alguien está en desacuerdo solo grite.

¿Por qué Julia y no lo obvio (Python/Go/Rust)?

  • Performance nativa: Julia compila a código máquina vía LLVM. Para operaciones criptográficas intensivas (derivación de claves, hashing repetido), esto importa.
  • Sintaxis expresiva: Puedo escribir matemáticas complejas (como cálculo de entropía) de forma que parece… matemáticas.
  • Dispatch múltiple: Puedo definir diferentes comportamientos según el tipo de entrada sin convertir mi código en un zoológico de if/else.
  • REPL interactivo: Desarrollo rápido, testeo en tiempo real, ajustes sobre la marcha.
  • Sorpresa: Porque nadie lo espera y eso me gusta.

Arquitectura: ¿Qué hace “profesional” a un gestor de contraseñas?

Requisitos de seguridad

  • Cifrado real: Simulación de AES-256-GCM (en el demo uso XOR + derivación de claves, pero la estructura está lista para reemplazar con Nettle.jl)
  • Derivación de claves: PBKDF2 con 100,000 iteraciones (preparado para Argon2)
  • Salt único: Cada entrada cifrada usa su propio salt aleatorio criptográficamente seguro
  • Zero‑knowledge architecture: La contraseña maestra nunca se almacena, solo se deriva una clave de ella
  • Generación segura: Uso de Random de Julia con fuentes criptográficamente seguras

Features funcionales

  • 🎲 Generador de contraseñas con opciones configurables
  • 📊 Calculadora de entropía (la estrella del show)
  • 💾 Almacenamiento cifrado en JSON
  • 🔍 Comparador de contraseñas
  • 🎨 Interfaz CLI intuitiva

Módulo de entropía: La parte interesante

¿Qué es la entropía?

Entropía, en criptografía, es una medida de incertidumbre. Específicamente, cuántos bits de información impredecible contiene tu contraseña. Se calcula así:

H = L * log2(R)
  • L = longitud de la contraseña
  • R = tamaño del “pool” de caracteres posibles

Ejemplo visual

Contraseña débil típica

Password123!
  • Longitud: 12 caracteres
  • Pool detectado: minúsculas (26) + mayúsculas (26) + dígitos (10) + símbolos (32) = 94 caracteres
  • Entropía: 12 × log₂(94) ≈ 78.5 bits
  • Tiempo estimado de cracking: ~95 años (GPU moderna)

Problema real: es una palabra del diccionario y sigue un patrón predecible, por lo que un ataque de diccionario la rompe en minutos.

Contraseña fuerte generada

xK9#mL2$pQ7@vR4!nF
  • Longitud: 18 caracteres
  • Pool: 94 caracteres (uso completo)
  • Entropía: 18 × log₂(94) ≈ 118 bits
  • Tiempo estimado de cracking: ~1.05 × 10¹⁶ años (prácticamente infinito)

Implementación en Julia

Cálculo de entropía

function calculate_entropy(password::String)::Float64
    if isempty(password)
        return 0.0
    end

    # Detectar el pool de caracteres usado
    has_lowercase = any(c -> islowercase(c), password)
    has_uppercase = any(c -> isuppercase(c), password)
    has_digits    = any(c -> isdigit(c), password)
    has_special   = any(c -> !isalnum(c) && !isspace(c), password)

    # Calcular tamaño del pool
    pool_size = 0
    pool_size += has_lowercase ? 26 : 0
    pool_size += has_uppercase ? 26 : 0
    pool_size += has_digits    ? 10 : 0
    pool_size += has_special   ? 32 : 0

    # Fórmula de Shannon
    entropy = length(password) * log2(pool_size)
    return entropy
end

Generador de contraseñas

function generate_password(;
    length::Int=16,
    use_lowercase::Bool=true,
    use_uppercase::Bool=true,
    use_digits::Bool=true,
    use_special::Bool=true
)::String
    charset = Char[]
    use_lowercase && append!(charset, LOWERCASE)
    use_uppercase && append!(charset, UPPERCASE)
    use_digits    && append!(charset, DIGITS)
    use_special   && append!(charset, SPECIAL)

    # Generación criptográficamente segura
    password = String([rand(charset) for _ in 1:length])
    return password
end

Derivación de claves (PBKDF2)

function derive_key(master_password::String, salt::Vector{UInt8}, iterations::Int=100_000)::Vector{UInt8}
    # Aquí iría la llamada a una implementación de PBKDF2, por ejemplo usando
    # Crypto.jl o Nettle.jl. En el demo se muestra la estructura básica.
    # key = pbkdf2_hmac_sha256(master_password, salt, iterations, 32)
    # return key
end

(El resto del código del gestor, manejo de JSON cifrado, CLI y pruebas, está disponible en el repositorio del proyecto.)

Back to Blog

Related posts

Read more »