Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Password Generator CLI

Generador de contraseñas y passphrases por consola escrito en Java 21, con arquitectura modular y sin dependencias externas más allá de JUnit 5 para los tests.

Ofrece dos modos de uso:

  • Interactivo (menú por consola con prompts y colores ANSI).
  • Batch / CLI con argumentos, pensado para scripts y automatización.

Además incluye análisis de fortaleza, verificación contra Have I Been Pwned mediante k-anonimato, copia al portapapeles y guardado cifrado con AES-256-GCM.


Tabla de contenidos


Características

  • Generación aleatoria criptográficamente segura (SecureRandom.getInstanceStrong()).
  • Mezcla Fisher-Yates para distribución uniforme del resultado.
  • Políticas de contraseña configurables (obligatoriedad de mayúsculas, minúsculas, números y especiales; exclusión de ambiguos, espacios y caracteres arbitrarios).
  • Passphrases estilo Diceware con la EFF Large Wordlist (7 776 palabras, ~12.9 bits de entropía por palabra).
  • Palabras propias en las passphrases con mezcla y sanitizado automático.
  • Análisis de fortaleza con entropía aproximada, detección de patrones débiles (palabras comunes, leet, secuencias numéricas, repeticiones) y estimaciones de crack time en tres escenarios.
  • Verificación contra Have I Been Pwned enviando solo los primeros 5 caracteres del SHA-1 (k-anonimato).
  • Copia al portapapeles desde ambos modos.
  • Guardado en .txt con o sin cifrado AES-256-GCM + PBKDF2-HmacSHA256 (200 000 iteraciones) protegido con contraseña maestra.
  • Modo decrypt para leer los vaults cifrados desde CLI.
  • Tipos técnicos HEX y URL_SAFE para tokens de API, IDs de sesión y magic links.
  • Avisos y tips contextuales guiando al usuario en cada decisión de seguridad.
  • 134 tests unitarios con JUnit 5 (sin red, sin dependencias externas).

Tipos de contraseña

Tipo Descripción
ALL Letras, números y caracteres especiales
LETTERS Solo letras (mayúsculas y minúsculas)
UPPERCASE Solo letras mayúsculas
LOWERCASE Solo letras minúsculas
NUMBERS Solo números
SPECIALS Solo caracteres especiales
LETTERS_NUMBERS Letras y números
NUMBERS_SPECIAL Números y caracteres especiales
HEX 0-9 a-f — tokens de API, IDs de sesión, hashes
URL_SAFE A-Z a-z 0-9 - _ — tokens URL-safe (JWT-ish)

Las políticas por defecto se aplican automáticamente según el tipo:

  • Estricta para ALL, LETTERS_NUMBERS, NUMBERS_SPECIAL — exige al menos un carácter de cada categoría permitida.
  • Flexible para los tipos de categoría única — sin requisitos mínimos.
  • Raw para HEX y URL_SAFE — sin requisitos ni exclusiones por defecto, para que el charset llegue intacto (0-9 se conserva en HEX aunque excludeAmbiguous esté activo en otras políticas).

En el menú interactivo cada tipo aparece con una descripción corta al lado (HEX — hexadecimal 0-9 a-f — tokens API, IDs sesion, hashes).


Cómo ejecutar

Desde el código fuente (Maven)

git clone https://github.com/pier0del/Password_Generator.git
cd Password_Generator/PasswordGenerator
mvn clean package
java -jar target/password-generator-1.0.0.jar

Sin argumentos arranca el menú interactivo. Con argumentos entra en modo batch.


Modo interactivo

 =========================================
      GENERADOR DE CONTRASEÑAS - CLI
 =========================================
Tip: tambien puedes usarlo sin menu pasando argumentos.
     Ejecuta con --help para ver la sintaxis.
     Ejemplo: password-generator password --length 20 --count 5

--- MENU PRINCIPAL ---
1. Generar contraseña
2. Generar passphrase
3. Analizar fortaleza de un texto
4. Descifrar vault (.txt cifrado)
5. Salir

Al generar (opciones 1 y 2) el menú pide también cuántos secretos generar (Enter = 1). Con más de uno se imprime la lista numerada y los prompts posteriores actúan sobre la tanda (HIBP verifica cada uno, copiar copia todos al portapapeles separados por saltos de línea, guardar concatena todos).

Tras generar, el programa ofrece:

  1. Reporte de fortaleza (entropía, patrones, crack time) — solo si se generó uno.
  2. Verificar contra HIBP (opcional, requiere red).
  3. Copiar al portapapeles (opcional).
  4. Guardar en archivo .txt (opcional, con o sin cifrado AES-GCM).

Los prompts de contraseña maestra usan System.console().readPassword() cuando está disponible, por lo que no se muestra en pantalla.

La opción 3 (Analizar fortaleza) equivale al modo analyze del batch: pide un texto y muestra el reporte completo sin generar nada.


Modo batch / CLI

Sintaxis general:

password-generator                                    → menú interactivo
password-generator --help
password-generator password  --length N [opciones]
password-generator passphrase (--words N | --custom "w1,w2,...") [opciones]
password-generator analyze "<texto>"
password-generator decrypt --file <vault.txt> [--master-password X]

Opciones comunes

Flag Descripción
--count N Cuántos generar (default 1)
--copy Copia el último generado al portapapeles
--save <ruta.txt> Guarda todos en un archivo (append). Añade .txt si falta
--no-strength Omite el reporte de fortaleza en la salida
--check-hibp Verifica contra Have I Been Pwned (k-anonimato, requiere red)
--encrypt Cifra el --save con AES-256-GCM y contraseña maestra
--master-password STR Contraseña maestra (o env PWGEN_MASTER_PASSWORD)

Opciones de password

Flag Descripción
--type TIPO Ver Tipos de contraseña (default ALL)
--length N Longitud (obligatorio)
--require-upper Exige al menos una mayúscula
--require-lower Exige al menos una minúscula
--require-number Exige al menos un dígito
--require-special Exige al menos un especial
--no-requirements Desactiva todos los --require-*
--exclude-ambiguous Excluye o 0 I l 1
--exclude-problematic Excluye " ' \ `

Opciones de passphrase

Flag Descripción
--words N Cantidad de palabras (3..10)
--custom "w1,w2,…" Usa tus propias palabras (3..10)
--separator STR Separador entre palabras (default -)
--capitalize Capitaliza cada palabra
--number Añade un número al final

Ejemplos

# 5 contraseñas de 20 chars, tipo ALL con política estricta
password-generator password --length 20 --count 5

# Passphrase de 5 palabras, capitalizada, con número y copiada al portapapeles
password-generator passphrase --words 5 --capitalize --number --copy

# Contraseña de 16 chars, guardada cifrada
export PWGEN_MASTER_PASSWORD='mi-clave-maestra'
password-generator password --length 16 --save vault.txt --encrypt

# Verificar filtraciones
password-generator password --length 24 --check-hibp

# Descifrar el vault
password-generator decrypt --file vault.txt

# Analizar la fortaleza de un texto
password-generator analyze "MiClave123!"

Avisos contextuales (stderr)

El modo batch imprime avisos a stderr en situaciones concretas para no ensuciar stdout:

Disparador Aviso
--save sin --encrypt Recomienda cifrar y sugiere la carpeta secrets/
--check-hibp Explica que solo se envían 5 chars del SHA-1 (k-anonimato)
passphrase --custom Advierte que las palabras propias suelen ser menos seguras que las aleatorias
--encrypt con éxito Recuerda cómo descifrar: password-generator decrypt --file X

stdout mantiene su formato limpio (un secreto por línea + metadatos #), pipeable sin ruido.

Códigos de salida

Código Significado
0 OK
1 Error de sintaxis en los argumentos
2 Error del generador (configuración inválida)
3 Error inesperado

La salida a stdout es un secreto por línea (fácil de pipear); metadatos como # fortaleza=… o # hibp=clean empiezan con #; los errores salen a stderr.


Análisis de fortaleza

Cada secreto generado (o el argumento de analyze) se evalúa con un enfoque heurístico:

  • Entropía aproximada basada en el charset detectado.
  • Patrones débiles: palabras comunes (incluyendo desleet automático de p@ssw0rd), secuencias numéricas ascendentes/descendentes de 3+ dígitos, sustituciones predecibles.
  • Repeticiones de 3+ caracteres.
  • Crack time estimado en 3 escenarios: online limitado (100/h), offline rápido (10¹⁰/s), hardware especializado (10¹²/s).

Niveles: MUY_DEBIL, DEBIL, MODERADA, FUERTE, MUY_ALTA.


Have I Been Pwned (k-anonimato)

Con --check-hibp (batch) o respondiendo s al prompt (interactivo), el secreto se verifica contra la base de datos pública de contraseñas filtradas de HIBP.

Nunca se envía la contraseña completa: se calcula su SHA-1 localmente, se envían solo los primeros 5 caracteres a api.pwnedpasswords.com/range/… y la comparación del resto se hace en local. El servidor no puede saber qué contraseña has consultado.

Se usa el header Add-Padding: true que HIBP recomienda para reforzar el k-anonimato con entradas falsas en la respuesta.

Salida en batch:

# hibp=clean            → no aparece en filtraciones
# hibp=pwned:9659365    → cantidad de veces filtrada
# hibp=error(...)       → sin red o timeout

Guardado cifrado (AES-256-GCM)

Cuando se activa el cifrado, el archivo .txt guarda:

PWGEN-VAULT-V1
iters=200000
salt=<base64 16 bytes>
iv=<base64 12 bytes>
ct=<base64 ciphertext + tag GCM>
  • AES-256-GCM garantiza confidencialidad y autenticación: si el archivo se manipula o la contraseña maestra es incorrecta, el descifrado falla con AEADBadTagException.
  • La clave se deriva con PBKDF2WithHmacSHA256, 200 000 iteraciones y salt aleatorio de 16 bytes.
  • El IV/nonce es aleatorio de 12 bytes y único por cifrado.
  • Al guardar sobre un vault existente se re-cifra el contenido anterior (append seguro) tras verificar la contraseña maestra.
  • Al terminar el flujo, el char[] con la contraseña maestra se borra de memoria (Arrays.fill(master, '\0')).

Cómo pasar la contraseña maestra en batch (por orden de preferencia):

  1. Variable de entorno PWGEN_MASTER_PASSWORD (no queda en el historial del shell).
  2. Flag --master-password STR.

Flujo seguro recomendado

El proyecto incluye secrets/ y vaults/ en el .gitignore, además de .env, .env.local y .env.*.local. Si guardas los vaults dentro de esas carpetas y la contraseña maestra en un .env, nunca se colará nada al repositorio aunque olvides revisar git status.

# 1. Carpeta ignorada por git
mkdir secrets

# 2. Contraseña maestra en variable de entorno (no queda en el historial)
export PWGEN_MASTER_PASSWORD='mi-clave-maestra'

# 3. Guardar cifrado dentro de secrets/
java -jar target/password-generator-1.0.0.jar password \
    --length 20 --count 5 \
    --save secrets/passwords.txt --encrypt

# 4. Leerlo mas tarde
java -jar target/password-generator-1.0.0.jar decrypt \
    --file secrets/passwords.txt

Alternativa con archivo .env (también ignorado):

echo 'PWGEN_MASTER_PASSWORD=mi-clave-maestra' > .env
set -a && source .env && set +a
java -jar target/password-generator-1.0.0.jar password \
    --length 20 --save secrets/passwords.txt --encrypt

Arquitectura

src/
└── main/
    ├── java/com/pieroapp/passwordgen/
    │   ├── cli/          → Main, CliArgs, BatchRunner
    │   ├── generator/    → PasswordGenerator, PassphraseGenerator
    │   ├── model/        → PasswordConfig, PassphraseConfig, PasswordType, TypeCapabilities
    │   ├── policy/       → PasswordPolicy
    │   ├── validator/    → PasswordValidator
    │   ├── strength/     → PasswordStrengthAnalyzer, StrengthLevel, PasswordStrengthReport
    │   ├── security/     → HibpChecker, SecretVault
    │   ├── util/         → RandomUtil, PasswordPools, WordList
    │   └── exception/    → excepciones personalizadas
    └── resources/
        └── eff-large-wordlist.txt   (7776 palabras, dominio público, EFF)

Diseño: separación estricta de capas, sin acoplamiento a System.in/System.out en la lógica de negocio. HibpChecker acepta un RangeFetcher inyectable para testear sin red; BatchRunner recibe PrintStream para stdout/stderr y es testeable end-to-end sin subprocesos.


Testing

mvn test

134 tests unitarios con JUnit 5, cero red, cero I/O real fuera de @TempDir:

Suite Nº tests Cubre
PasswordGeneratorTest 24 Generación, tipos (incl. HEX/URL_SAFE), políticas, exclusiones
PasswordValidatorTest 15 Validación y errores de configuración
PasswordPolicyTest 12 Constructor, factorías, rawPolicy vs noRequirementsPolicy
PassphraseGeneratorTest 13 Cantidad, separador, capitalize, custom
PasswordStrengthAnalyzerTest 11 Entropía, patrones, repeticiones
WordListTest 2 Carga del recurso EFF
HibpCheckerTest 8 k-anonimato con fetcher fake
SecretVaultTest 8 Roundtrip, tamper, wrong password
VaultExceptionTest 2 Jerarquía y preservación de causa
CliArgsTest 24 Parser de argumentos
BatchRunnerTest 15 Flujos end-to-end + HEX/URL_SAFE end-to-end

Tecnologías

  • Java 21
  • Maven (build & tests)
  • JUnit 5 (Jupiter)
  • APIs estándar de la JVM: java.security, javax.crypto, java.net.http, java.awt.datatransfercero dependencias externas en runtime

Autor

Desarrollado por Piero — proyecto educativo enfocado en buenas prácticas, seguridad aplicada y arquitectura limpia.


Licencias

  • Este proyecto: MIT — ver LICENSE.
  • Componentes de terceros y atribuciones: ver NOTICE.
    • La EFF Large Wordlist incluida en resources/ se distribuye bajo CC-BY-3.0 US (©️ Electronic Frontier Foundation).

About

Generador de contraseñas y passphrases en Java con modo de menu interactivo y por comandos Batch/CLI, Diccionario EFF Large Wordlist, incluye analisis de fortaleza, verificacion HIBP por (k-anonimato), cifrado AES-256-GCM con PBKDF2, tipos HEX/URL_SAFE para tokens, y 134 tests unitarios.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages