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.
- Características
- Tipos de contraseña
- Cómo ejecutar
- Modo interactivo
- Modo batch / CLI
- Análisis de fortaleza
- Have I Been Pwned (k-anonimato)
- Guardado cifrado (AES-256-GCM)
- Arquitectura
- Testing
- Tecnologías
- 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
.txtcon 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).
| 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
HEXyURL_SAFE— sin requisitos ni exclusiones por defecto, para que el charset llegue intacto (0-9se conserva en HEX aunqueexcludeAmbiguousesté 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).
git clone https://github.com/pier0del/Password_Generator.git
cd Password_Generator/PasswordGenerator
mvn clean package
java -jar target/password-generator-1.0.0.jarSin argumentos arranca el menú interactivo. Con argumentos entra en modo batch.
=========================================
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:
- Reporte de fortaleza (entropía, patrones, crack time) — solo si se generó uno.
- Verificar contra HIBP (opcional, requiere red).
- Copiar al portapapeles (opcional).
- 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.
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]
| 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) |
| 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 " ' \ ` |
| 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 |
# 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!"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ó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.
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.
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
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):
- Variable de entorno
PWGEN_MASTER_PASSWORD(no queda en el historial del shell). - Flag
--master-password STR.
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.txtAlternativa 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 --encryptsrc/
└── 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.
mvn test134 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 |
- Java 21
- Maven (build & tests)
- JUnit 5 (Jupiter)
- APIs estándar de la JVM:
java.security,javax.crypto,java.net.http,java.awt.datatransfer— cero dependencias externas en runtime
Desarrollado por Piero — proyecto educativo enfocado en buenas prácticas, seguridad aplicada y arquitectura limpia.