Las cuentas de usuario de MySQL se listan en la tabla
user
de la base de datos
mysql
. Cada cuenta MySQL tiene una
contraseña asiganada, aunque lo que se guarda en la columna
Password
de la tabla user
no es una versión en texto plano de la contraseña, si no un
valor hash computado a partir de la misma. Los valores hash de
las contraseñas se obtienen a partir de la función
PASSWORD()
.
MySQL usa contraseñas en dos fases de la comunicación cliente/servidor:
Cuando un cliente trata de conectar al servidor, hay un paso
inicial de autenticación en el que el cliente debe
presentar una contraseña cuyo valor hash coincida con el
valor hash almacenado en la tabla user
para la cuenta que el cliente quiere usar.
Una vez que el cliente conecta, puede (si tiene los
suficientes permisos) cambiar o incializar los hashes de las
contraseñas para las cuentas listadas en la tabla
user
. El cliente puede hacerlo mediante
la función PASSWORD()
para generar el
hash de la contraseña, o mediante los comandos
GRANT
o SET PASSWORD
.
En otras palabras, el servidor usa los
valores hash durante la autenticación cuando un cliente trata
de conectar por primera vez. El servidor
genera valores hash si un cliente conectado
invoca la función PASSWORD()
o usa los
comandos GRANT
o SET
PASSWORD
para inicializar o cambiar una contraseña.
El mecanismo de hash de contraseñas se actualizó en MySQL 4.1. para proporcionar una mejor seguridad y para reducir el riesgo de intercepción de contraseñas. Sin embargo, este nuevo mecanismo sólo lo entienden los servidores y clientes MySQL 4.1. (y versiones posteriores), lo cual puede acarrear algunos problemas de compatibilidad. Un cliente 4.1. o posterior puede conectar a un servidor pre-4.1, ya que el cliente entiende los mecanismos de hashing de contraseñas antiguos y nuevos. Sin embargo, un cliente pre-4.1. que trate de conectar a un servidor 4.1. o posterior puede tener problemas. Por ejemplo, un cliente 3.23 mysql que trate de conectar a un servidor 5.0 puede fallar con el siguiente mensaje de error:
shell> mysql -h localhost -u root Client does not support authentication protocol requested by server; consider upgrading MySQL client
Otro ejemplo común es cuando se trata de usar la antigua extensión de mysql para PHP tras actualizar a MySQL 4.1 o posterior. (Consulte Sección 24.3.1, “Problemas comunes con MySQL y PHP”.)
La siguiente discusión describe las diferencias entre el
antiguo y nuevo mecanismo de contraseñas, y qué debe hacer si
actualiza su servidor pero necesita matener compatibilidad con
clientes versión pre-4.1. Puede encontrar información
adicional en Sección A.2.3, “Client does not support authentication protocol
”. Esta información es
de especial importancia para programadores de PHP que migran de
versiones de bases de datos MySQL 4.0 o anteriores a versiones
4.1. o posteriores.
Nota: Esta discusión contrasta el comportamiento 4.1. con el pre-4.1, pero el comportamiento 4.1 descrito aquí realmente empieza en el 4.1.1. MySQL 4.1.0 es una versión ``particular'' ya que tiene mecanismos ligeramente distintos a los implementados en 4.1.1 y posteriormente. Las diferencias entre 4.1.0 y reciones más recientes se describen con más detalle en Manual de referencia de MySQL 4.1.
Antes de MySQL 4.1, los hashes de contraseñas computados por la
función PASSWORD()
tienen una longitud de 16
bytes. Tales hashes tienen este aspecto:
mysql> SELECT PASSWORD('mypass'); +--------------------+ | PASSWORD('mypass') | +--------------------+ | 6f8c114b58f2ce9e | +--------------------+
La columna Password
de la tabla
user
(en la que se guardan los hashes)
también tiene una longitud de 16 bytes antes de MySQL 4.1.
En MySQL 4.1, la función PASSWORD()
se
modificó para producir un valor hash más largo de 41-bytes:
mysql> SELECT PASSWORD('mypass'); +-----------------------------------------------+ | PASSWORD('mypass') | +-----------------------------------------------+ | *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 | +-----------------------------------------------+
Por consiguiene, la columna Password
en la
tabla user
debe tener una longitud de 41
bytes para almacenar estos valores:
Si realiza una nueva instalación de MySQL 5.0, la columna
Password
se amplía a 41 bytes
automáticamente.
Actualizar desde MySQL 4.1 (4.1.1 o posterior en la serie 4.1 ) a MySQL 5.0 no debería afectar a nada de todo esto, ya que ambas versiones usan el mismo mecanismo de hash de contraseñas. Si desea actualizar una versión antorior de MySQL a 5.0, debe actualizar primero a la versión 4.1, y luego actualizar la instalación de 4.1. a 5.0.
Una columna Password
más amplia puede
almacenar hashes de contraseñas en el antiguo y nuevo formato.
El formato de cualquier valor hash de una contraseña puede
determinarse de dos formas:
La diferencia óbvia es la longitud (16 bytes contra 41 bytes).
Una segunda diferencia es que los hashes de contraseñas en
el nuevo formato simpre empieza con un carácter
'*
', mientras que una contraseña en el
antiguo formato nunca lo hace.
El hash de la contraseña más larga tiene mejores propiedades criptográficas, y la autenticación de clientes basada en hashes largos es más segura que la basada en los antiguos hashes cortos.
Las diferencias entre hashes cortos y largos son relevantes para cómo el servidor usa las contraseñas durante la autenticación y por cómo genera los hashes de contraseñas para clientes conectados que realizan operaciones de cambio de contraseña.
La forma en que el servidor usa los hashes de contraseñas
durante la autenticación se ve afectada por la longitud de la
columna Password
:
Si la columna es corta, sólo se usa autenticación de hash cortos.
Si la columna es larga, puede soportar hashes cortos o largos, y el servidor puede usar cualquier formato:
Clientes pre-4.1 pueden conectar, aunque sólo conocen el antiguo mecanismo de hash, pueden autenticar sólo para cuentas que tengan hashes cortos.
Clientes 4.1 y posterior pueden autenticar para cuentas que tengan hashes cortos o largos.
Para cuentas con hash corto, el proceso de autenticación es un poco más seguro para clientes 4.1 y posteriores que para clientes más antiguos. Respecto a seguridad, el gradienet de menos a más seguro es:
Cliente pre-4.1 autenticando con hash de contraseña corto
Cliente 4.1 o posterior autenticando con hash de contraseña corto.
Cliente 4.1 o posterior autenticando con hash de contraseña largo.
La forma en que el servidor genera los hashes de contraseña
para clientes conectados se ve afectado por la longitud de la
columna Password
y por la opción
--old-passwords
. Un servidor 4.1. o posterior
genera hashes largos sólo si se cumplen ciertas condiciones: La
columna Password
debe ser lo suficientemente
larga para guardar valores largos y no debe darse la opción
--old-passwords
. Estas condiciones se aplican
como sigue:
La columna Password
debe ser lo
suficientemente grande para guardar hashes largos (41
bytes). Si la columna no se ha actualizado y todavía tiene
la longitud pre-4.1 de 16 bytes, el servidor entiende que no
puede guardar hashes largos y genere sólo hashes cortos
cuando un cliente realiza opraciones de cambio de
contraseña mediante PASSWORD()
,
GRANT
, o SET PASSWORD
.
Este es el comportamiento que ocurre si ha actualizado a 4.1
pero no ha ejecutado todavía el script
mysql_fix_privilege_tables para ensanchar
la columna Password
.
Si la columna Password
es amplia, puede
almacenar tanto hashes de contraseñas largos como cortos.
En este caso, PASSWORD()
,
GRANT
, y SET PASSWORD
generan hashes largos a no ser que el servidor se haya
iniciado con la opción --old-passwords
.
Este opción fuerza al servidor a generar hashes de
contraseñas cortos.
El propósito de la opción --old-passwords
es permitirle mantener compatibilidad con clientes anteriores a
4.1 bajo circunstancias donde el servidor generaría hashes de
contraseñas largos. La opción no afecta la autenticación
(clientes 4.1. y posteriores pueden usar cuentas que tengan
hashes largos de contraseña), pero no evita la creación de
hashes largos de contraseñas en la tabla
user
como resultado de una operación de
cambio de contraseña. Si eso ocurre, la cuenta no puede usarse
por clientes pre-4.1. Sin la opción
--old-passwords
, es posible el siguiente
escenario no deseable:
Un cliente viejo trata de conectar a una cuenta que tenga hash de contraseña corto.
El cliente cambia su propia contraseña. Sin
--old-passwords
, esto acaba con la cuenta
con un hash de contraseña largo.
La siguiente vez que el viejo cliente trate de conectar a la cuenta, no podrá, ya que la cuenta tiene un hash de contraseña largo que requiere un nuevo mecanismo de hash durante la autenticación. (Una vez que una cuenta tiene un hash de contraseña largo en la tabla de usuario, sólo clientes 4.1. y posteriores pueden autenticar, ya que clientes pre-4.1. no entienden hashes largos.)
Este escenario ilustra que, si debe soportar clientes pre-4.1,
es peligroso ejecutar un servidor 4.1 o posterior sin usar la
opción --old-passwords
. Ejecutando el
servidor con --old-passwords
, las operaciones
de cambio de contraseña no generan hashes largos de contraseña
y por lo tanto, no provocan que las cuentas sean inaccesibles
para clientes antiguos. (Aquellos clientes no pueden bloquearse
a ellos mismos mediante el cambio de su contraseña y acabando
con un hash de contraseña largo.)
La desventaja de la opción --old-passwords
es que cualquier contraseña que cree o cambie usará hashes
cortos, incluso para clientes 4.1. Así, pierde la seguridad
adicional proporcionada por los hashes de contraseña largos. Si
quiere crear una cuenta que tiene un hash largo (por ejemplo,
para usar con un cliente 4.1), debe hacerlo mientras el servidor
se esté ejecutando sin --old-passwords
.
Los siguientes escenarios son posibles al ejecutar un servidor 4.1 o posterior, incluyendo servidores MySQL 5.0:
Escenario 1:Columna
Password
corta en tabla de usuario:
Sólo se pueden guardar hashes cortos en la columna
Password
.
El servidor usa sólo hashes cortos durante la autenticación del cliente.
Para clientes conectados, las operaciones de generación de
hashes de contraseñas mediante
PASSWORD()
, GRANT
, o
SET PASSWORD
usan hashes cortos
exclusivamente. Cualquier cambio a una contraseña de una
cuenta resulta en una cuenta teniendo un hash de contraseña
corto.
La opción --old-passwords
puede usarse
pero es supérflua ya que con una columna
Password
corta, el servidor genera sólo
hashes de contraseña cortos de todas formas..
Escenario 2: Columna
Password
larga; servidor no arrancado con la
opción --old-passwords
:
Hashes cortos o largos pueden almacenarse en la columna
Password
.
Clientes 4.1 y posteriores (incluyendo clientes 5.0) pueden autenticar para cuentas que tengan tanto hashes cortos como largos.
Clientes pre-4.1 pueden autenticar sólo para cuentas que tengan hashes cortos.
Para clientes conectados, operaciones generadoras de hash
como PASSWORD()
,
GRANT
, o SET PASSWORD
usan hashes largos exclusivamente. Un cambio en la
contraseña de una cuenta resulta en dicha cuenta con un
hash largo.
Como se ha indicado, un peligro en este escenario es que es
posible para cuentas con hash corto quedar inaccesibles para
clientes pre-4.1. Un cambio en tales contraseñas hecho via
GRANT
, PASSWORD()
, o
SET PASSWORD
resulta en la cuenta con una
contraseña larga. A partir de ahí, ningún cliente pre-4.1
puede autenticar a dicha cuenta hasta que el cliente actualice a
4.1.
Para tratar este problema, puede cambiar una contraseña de
forma especial. Por ejemplo, normalmente usa SET
PASSWORD
como sigue para cambiar una contraseña de
cuenta:
mysql> SET PASSWORD FOR 'some_user
'@'some_host
' = PASSWORD('mypass');
Para cambiar la contraseña pero crear un hash corto, use la
función OLD_PASSWORD()
en su lugar:
mysql> SET PASSWORD FOR 'some_user
'@'some_host
' = OLD_PASSWORD('mypass');
OLD_PASSWORD()
es útil para situaciones en
que explícitamente quiera generar un hash corto.
Escenario 3: Columna
Password
larga; servidor 4.1 o posterior
arrancado con la opción --old-passwords
:
Hashes crotos o largos pueden guardarse en la columna
Password
.
Clientes 4.1 y posteriores pueden autenticar para cuentas
que tengan hashes cortos o largos ( pero tenga en cuenta que
es posible crear hashes largos sólo cuando el servidor se
arranca sin --old-passwords
).
Clientes pre-4.1 clients pueden autenticar sólo para cuentas que tengan hashes cortos.
Para clientes conectados, operaciones de generación de
hashes como PASSWORD()
,
GRANT
, o SET PASSWORD
usan hashes cortos exclusivamente. Cualquier cambio en la
contraseña de una cuenta resulta en que dicha cuenta tenga
un hash de contraseña corto.
En este escenario, no puede crear cuentas que tengan hashes de
contraseña cortos, ya que la opción
--old-passwords
evita la generación de
hashes largos. También, si crea una cuenta con hashes largos
antes de usar la opción --old-passwords
,
cambiar la contraseña de la cuenta mientras
--old-passwords
está en efecto resulta en la
cuenta teniendo una contraseña corta, causando que se pierdan
los beneficios de seguridad de un hash más largo.
Las desventajas de estos escenarios pueden resumirse así:
En el escenario 1, no puede beneficiarse de hashes largos que proporcionan más seguridad de autenticación.
En el escenario 2, las cuentas con hashes cortos son
inaccesibles para clientes pre-4.1 si cambia sus contraseñas
sin usar explícitamente OLD_PASSWORD()
.
En el escenario 3, --old-passwords
evita que
las cuentas con hashes cortos sean inaccesibles, pero las
operaciones de cambio de contraseña causa que las cuentas con
hashes largos vuelvan a ser hashes cortos, y no puede volver a
hacerlos hashes largos mientras
--old-passwords
tenga efecto.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.