¿Por qué generar un hash APR1-MD5 en línea?
La autenticación HTTP Basic sigue siendo la forma más rápida de cerrar un panel de administración, una preproducción o un cuadro de mando interno. Se apoya en un fichero .htpasswd en el que cada línea asocia un usuario a una contraseña hasheada, nunca en claro.
El problema: para producir ese hash normalmente hace falta el comando htpasswd, es decir el paquete apache2-utils en Debian o httpd-tools en RHEL. En un equipo Windows, en un alojamiento compartido o desde una interfaz web, ese comando suele faltar.
Tres situaciones en las que este generador saca del apuro:
- Proteger una preproducción → Cerrar el acceso a un entorno de pruebas antes de que Google lo indexe
- Añadir una cuenta sin acceso SSH → Crear la línea desde el navegador y pegarla con el gestor de ficheros de tu proveedor
- Migrar una configuración → Reconstruir un fichero
.htpasswdperdido a partir de las credenciales conocidas
Cómo usar el generador en 3 pasos
Paso 1: introducir el usuario y la contraseña
Escribe el nombre de la cuenta y su contraseña. El campo está oculto por defecto; pulsa el icono del ojo para releer lo que has escrito antes de validar.
Paso 2: dejar que se genere la sal
En casi todos los casos, deja vacío el campo de la sal: el servidor generará una sal aleatoria de 8 caracteres. Rellénalo solo para reproducir un hash existente de forma idéntica.
Paso 3: copiar la línea
Se muestran dos resultados: el hash solo y la línea .htpasswd completa. Copia esta última, pégala en tu fichero y recarga la configuración del servidor.
Anatomía de una línea .htpasswd
Una línea se divide en dos campos separados por dos puntos:
admin:$apr1$Xq7nD2mR$5CqLZ.k1qLkOvVQ0uZ9Yl.
El segundo campo se descompone a su vez en tres partes delimitadas por $:
| Parte | Ejemplo | Función |
|---|---|---|
| Identificador de algoritmo | apr1 | Indica al servidor que se trata del MD5 con sal de Apache |
| Sal | Xq7nD2mR | 8 caracteres aleatorios, guardados en claro en el fichero |
| Resumen | 5CqLZ.k1qLkOvVQ0uZ9Yl. | 22 caracteres, resultado de las 1.000 iteraciones |
La sal no es un secreto: se puede leer en el fichero. Su función es impedir que una tabla precalculada (rainbow table) sirva para recuperar la contraseña, y garantizar que dos cuentas con la misma contraseña no compartan resumen.
Qué hace realmente el algoritmo $apr1$
APR1-MD5 no es un simple md5(contraseña + sal). Encadena:
- Dos resúmenes iniciales - uno sobre
contraseña + $apr1$ + sal, y otro sobrecontraseña + sal + contraseña - Una mezcla que depende de la longitud - fragmentos del segundo resumen se reinyectan en el primero, byte a byte
- 1.000 iteraciones - en cada vuelta se recombinan contraseña, sal y resumen anterior según un patrón que depende del número de vuelta
- Una codificación base64 «crypt» - los 16 bytes finales se releen en un orden entrelazado y se codifican con el alfabeto
./0-9A-Za-z
Esas 1.000 iteraciones marcan la diferencia frente a un MD5 a secas: multiplican por mil el coste de cada intento, y ralentizan en la misma medida un ataque por diccionario.
Proteger un directorio con Apache
1. Crear el fichero
Coloca tu fichero .htpasswd fuera de la raíz web, para que nunca se sirva por HTTP:
/var/www/secrets/.htpasswd
2. Declarar la protección
En el .htaccess del directorio que quieres proteger, o en el bloque <Directory> de tu VirtualHost:
AuthType Basic
AuthName "Zona restringida"
AuthUserFile /var/www/secrets/.htpasswd
Require valid-user
3. Recargar la configuración
sudo apachectl configtest && sudo systemctl reload apache2
En nginx, ese mismo par de ficheros se declara así:
location /admin/ {
auth_basic "Zona restringida";
auth_basic_user_file /var/www/secrets/.htpasswd;
}
APR1-MD5 frente a los demás formatos .htpasswd
| Formato | Prefijo | Coste de cálculo | Veredicto |
|---|---|---|---|
| bcrypt | $2y$ | Ajustable (factor de coste) | Recomendado para cualquier proyecto nuevo |
| APR1-MD5 | $apr1$ | 1.000 iteraciones de MD5 | Aceptable, compatibilidad máxima |
| SHA-1 | {SHA} | 1 iteración, sin sal | Evítalo: sin sal, vulnerable a tablas |
| crypt() DES | ninguno | 25 iteraciones, truncado a 8 caracteres | Obsoleto, no lo uses |
En resumen: si tu servidor acepta bcrypt (htpasswd -B), úsalo. APR1-MD5 es la mejor opción restante cuando bcrypt no está disponible, y es infinitamente mejor que un {SHA} sin sal.
Verificar el hash desde la línea de comandos
Con la misma sal, el resultado de esta herramienta es idéntico al de las utilidades del sistema:
# Con htpasswd (paquete apache2-utils / httpd-tools)
htpasswd -nbm admin miContrasena
# Con OpenSSL, imponiendo la sal
openssl passwd -apr1 -salt Xq7nD2mR miContrasena
El segundo ejemplo sirve además para comprobar esta herramienta: introduce la misma sal en el formulario y deberías obtener exactamente la misma cadena.
Para verificar que una contraseña corresponde a una línea existente, lee la sal dentro del hash guardado y repite el cálculo con esa sal.
FAQ - Preguntas frecuentes
P: ¿Qué es el formato $apr1$?
R: Es el formato de hash histórico de Apache, también llamado APR1-MD5. Aplica 1.000 iteraciones de MD5 sobre la contraseña y una sal de 8 caracteres, y codifica el resultado en el alfabeto base64 de crypt. El prefijo $apr1$ actúa como identificador del algoritmo.
P: ¿Sigue siendo seguro APR1-MD5?
R: Es mucho más sólido que un MD5 a secas, pero sigue siendo rápido de calcular para un atacante con GPU. Para un proyecto nuevo, opta por bcrypt con htpasswd -B. APR1-MD5 mantiene su interés cuando prima la compatibilidad: versiones antiguas de Apache, nginx sin soporte de bcrypt, dispositivos de red.
P: ¿Funciona este hash con nginx?
R: Sí. El módulo ngx_http_auth_basic_module de nginx lee el formato de Apache, $apr1$ incluido. La línea generada se usa tal cual con auth_basic_user_file.
P: ¿Por qué obtengo un hash distinto cada vez?
R: Porque en cada generación se crea una sal aleatoria nueva. Los dos hashes son válidos para la misma contraseña: al verificar, el servidor lee la sal guardada en el hash y repite el cálculo. Rellena el campo de la sal si quieres un resultado reproducible.
P: ¿Se guarda la contraseña en algún sitio?
R: No. Viaja por HTTPS hasta la API de CaptainDNS durante el cálculo y luego se descarta. Ni base de datos ni registro con la contraseña en claro.
P: ¿Puedo usar acentos o símbolos?
R: Sí, el cálculo se hace sobre los bytes UTF-8 de la contraseña. Un aviso: un cliente HTTP antiguo puede codificar los caracteres no ASCII de otra forma, lo que haría fallar la autenticación. Ante la duda, quédate en ASCII.
P: ¿Dónde hay que colocar el fichero .htpasswd?
R: Fuera de la raíz web, por ejemplo en /var/www/secrets/. Si está en un directorio servido por HTTP, cualquier visitante podría descargarlo y atacar los hashes sin conexión.
Herramientas complementarias
| Herramienta | Utilidad |
|---|---|
| Generador de contraseñas | Crear una contraseña sólida antes de hashearla |
| Generador de hash | Calcular MD5, SHA-1, SHA-256 y SHA-512 de un texto |
| Codificador Base64 | Codificar la cabecera Authorization de una petición Basic |
| Analizador de cabeceras HTTP | Revisar las cabeceras que devuelve una zona protegida |
| Test HSTS | Asegurarte de que el acceso protegido va por HTTPS |
Recursos útiles
- Documentación de Apache - htpasswd (opciones del comando y formatos admitidos)
- Documentación de Apache - Autenticación (implantación de la autenticación Basic)
- RFC 7617 - The Basic HTTP Authentication Scheme (especificación del esquema Basic)
- RFC 1321 - MD5 (especificación de la función MD5)
Compromiso de confidencialidad
Tu contraseña se transmite a la API de CaptainDNS únicamente para calcular el hash, sobre una conexión cifrada. Ni se almacena ni se registra. Solo se conservan métricas técnicas anónimas (tiempo de procesamiento, código de respuesta).