Actualmente estoy en el proceso de migrar un servidor web antiguo.
El servidor antiguo usa autenticación básica con usuarios almacenados en una tabla MySQL y mod_auth_mysql
habilitados.
La contraseña se almacena con la función sha1 incorporada de Apache SELECT sha1('secret')
que funciona paramod_auth_mysql
Lamentablemente mod_auth_mysql
ya no es compatible. Por eso encontré mod_authn_dbd
como alternativa.
https://documentation.help/httpd-2.4-es/mod_authn_dbd.html
Ya logré tener todo en funcionamiento hasta el punto en que puedo iniciar sesión con autenticación básica y una contraseña fija.
<Location />
AuthType Basic
AuthName "Test"
AuthBasicProvider dbd
Require valid-user
AuthDBDUserPWQuery "SELECT '{SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M=' FROM users WHERE user = %s"
</Location>
Solo almaceno el hash sha1 en la tabla de usuarios. Mientras que los antiguos mod_auth_mysql
hashes aceptados generados por mysql ( SELECT sha1('test')=a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
) mod_authn_dbd no lo hacen.
De acuerdo ahttps://documentation.help/httpd-2.4-es/password_encryptions.html
SHA1 "{SHA}" + resumen SHA-1 codificado en Base64 de la contraseña.
Se aceptan contraseñas generadas por htpasswd.
htpasswd -bns user test
user:{SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M=
Ahora necesito convertir este valor a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
(almacenado en mi base de datos para la prueba de contraseña) a qUqP5cyxm6YcTAhz05Hph5gvu9M=
(valor aceptado para la prueba de contraseña) dentro de MySQL
ya lo intenté
SELECT to_base64(sha1('test')), to_base64(ucase(sha1('test'))), to_base64(lcase(sha1('test')));`
pero ninguno produce los resultados esperados.
Necesito una forma de convertir los hashes de mi contraseña existente al formato esperado o convencerme mod_authn_dbd
de que acepte mi hash sha1 existente.
Cualquier ayuda sería apreciada
Respuesta1
Respondiste tu propia pregunta con el ejemplo de PHP. La función pack() en PHP convierte representaciones hexadecimales de datos binarios (que es lo que los hashes SHA-1 normalmente se muestran como legibles por humanos) a su forma binaria original (no legible por humanos). Debes ejecutar to_base64() contra esta forma binaria del hash SHA-1 que generas de esta manera:
mysql> SELECT to_base64(unhex(sha1('test')));
+--------------------------------+
| to_base64(unhex(sha1('test'))) |
+--------------------------------+
| qUqP5cyxm6YcTAhz05Hph5gvu9M= |
+--------------------------------+
1 row in set (0.00 sec)
En este caso, obtendrá el resultado deseado sólo con MySQL.
Respuesta2
Esta no es una respuesta directa a mi pregunta, pero podría ser una solución. Encontré una publicación de blog donde alguien tuvo el mismo problema.
http://nileshbansal.blogspot.com/2008/06/password-encryption-mysql-apache-and.html
en los comentarios hay un enlace sobre cómo crear un hash compatible con htpasswd con php. Confirmé que esto da el mismo resultado que htpasswd -bns
el comando.
function sha1_to_htpasswd ( $user, $sha )
{
return $user . ':{SHA}' . base64_encode( pack( "H" . strlen( $sha ), $sha ) );
}
Si nadie conoce una solución mejor (solo mysql y sin php), probablemente extendería mi tabla de usuarios con una columna donde la contraseña esté almacenada de esta manera. Un poco redundante pero debería funcionar.