[+/-]
Les comptes utilisateurs de MySQL sont stockés dans la table
user
de la base mysql
.
Chaque compte MySQL a un mot de passe, même si ce qui est
stocké dans la colonne Password
de la table
user
n'est pas la version texte du mot de
passe, mais un hash calculé à partir du mot de passe. La
transformation est faîte avec la fonction
PASSWORD()
.
MySQL utilise les mots de passe en deux phases, lors de la communication client/serveur :
Premièrement, lorsqu'un client tente de se connecter au serveur, il y a une identification initial au cours de laquelle le client doit présenter un mot de passe dont la valeur hashée est la même que celle qui est présente dans la table d'utilisateur, pour le compte que le client veut utiliser.
Ensuite, après la connexion du client, il peut modifier ou
changer le mot de passe pour les utilisateurs du serveur
(s'il a les droits nécessaires pour cela). Le client peut
faire cela avec la fonction PASSWORD()
,
pour générer un autre mot de passe, ou en utilisant les
commandes GRANT
ou SET
PASSWORD
.
En d'autres termes, le serveur utilise les
valeurs hashées durant la phase d'identification, lorsque le
client tente de se connecter. Le serveur
génère des valeurs hash, si un client
appelle la fonction PASSWORD()
ou utilise les
commandes GRANT
ou SET
PASSWORD
.
Le mécanisme de modifications des mots de passe a été
modifié en MySQL 4.1, pour apporter une sécurité accrue et
réduire le risque de vol de mots de passe. Cependant, ce
nouveau mécanisme ne peut être compris que de la version 4.1,
et des clients MySQL 4.1, ce qui pose des problèmes de
compatibilité. Un client 4.1 peut se connecter sur un serveur
pre-4.1, car le client comprend les deux méthodes de hashage,
ancienne et nouvelle. Cependant, un client pre-4.1 qui tente se
de connecter à un serveur 4.1 aura des problèmes. Par exemple,
si un client mysql
4.0 essaie de se connecter
au serveur 4.1, il va recevoir l'erreur suivante :
shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
La discussion suivante décrit les différences entre les mécanismes de mots de paase, et ce que vous devez faire pour mettre à jour votre serveur en version 4.1, tout en conservant la compatibilité avec les clients pre-4.1.
Note : Cette discussion compare les comportements des versions 4.1 avec les versions d'avant (dites pre-4.1), mais le comportement 4.1 ne commence en réalité qu'avec la version 4.1.1. MySQL 4.1.0 est une version ``marginale'' car elle a un mécanisme légèrement différent de celui qui est implémenté en versions 4.1.1 et plus récent. Les différences entre les versions 4.1.0 et les versions plus récentes sont décrites ultérieurement.
Avant MySQL 4.1, les hashes calculés par
PASSWORD()
étaient longs de 16 octets. Des
hashes ressemblait à ceci :
mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e |
+--------------------+
La colonne Password
de la table
user
, dans laquelle les hash de mot de passse
sont stockés, faisait 16 octets de long, avant MySQL 4.1.
Depuis MySQL 4.1, la fonction PASSWORD()
a
été modifiée, pour produire une valeur de 41 octets, comme
ceci :
mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass') |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+
La colonne Password
de la table
user
a été aggrandie pour faire désormais
41 octets de long :
Si vous faites une nouvelle installation de MySQL 4.1, la
colonne Password
fera automatiquement 41
octets.
Si vous mettez à jour une ancienne installation, il est
recommandé d'utiliser le script
mysql_fix_privilege_tables
pour mettre à
jour la taille de la colonne Password
, de
16 à 41 octets. Le script ne modifie pas les valeurs
elles-mêmes, qui restent à 16 octets de long.
Une colonne Password
élargie peut stocker
les mots de passe dans les deux formats, ancien et nouveau. Le
format d'un hash de mot de passe peut être déterminer de deux
manières :
La différence principale et évidente est la taille : 16 octets et 41 octets.
La seconde différence est que les hashs au nouveau format
commencent par le caractère
‘*
’, alors que l'ancien
format ne le fait pas.
Plus le hash du mot de passe est long, meilleure sont ses caractéristiques de chiffrement, et l'identification des client, basée sur des hash longs, est plus sécuritaire que l'ancienne méthode, dont les hashs sont plus courts.
La différence de taille entre les mots de passe est utile lors de l'utilisation des mots de passe, pour l'identification, et lors de la génération des hashs pour la modification des mots de passe, sur le client.
La fa¸on de traiter le hash de mot de passe durant la phase
d'identification diffère, en fonction de la taille de la
colonne Password
:
Si la colonne est étroite, l'identification par hash court sera utilisée.
Si la colonne est large, elle peut contenir des hashs longs ou courts, et le serveur peut utiliser l'un ou l'autre des formats :
Les clients pre-4.1 peuvent se connecter, car ils connaissent l'ancien mécanisme de hashing, et ils peuvent s'identifier pour les comptes qui ont des mots de passe court.
Les clients 4.1 peuvent s'identifier pour les comptes qui ont des hash longs ou courts.
Pour les comptes à hash court, l'identification est un peut plus sécuritaire pour les clients 4.1 que pour les anciens clients. En terme de sécurité, le gradient de sécurité du plus faible au meilleur est :
Les clients pre-4.1 s'identifiant avec un hash court
Les clients 4.1 s'identifiant avec un hash court
Les clients 4.1 s'identifiant avec un hash long
La méthode de génération des hashs de mots de passe pour les
clients connectés est aussi affectée par la taille de la
colonne Password
, et par l'option
--old-passwords
. Un serveur 4.1 génère des
hashs longs sous certaines conditions : La colonne
Password
doit être assez grande pour
acceuillir un hash de mot de passe long, et l'option
--old-passwords
doit être inactive. Ces
conditions s'appliquent comme suit :
La colonne Password
doit être assez
grande pour acceuillir des hashs de mot de passe longs (41
octets). Si la colonne n'a pas été mise à jour, et
qu'elle a toujours la taille de 16 octets, le serveur le
remarque, et générera des hashs de mots de passe courts
lorsque le client va modifier son mot de passe avec
PASSWORD()
, GRANT
ou
SET PASSWORD
. Ce comportement survient si
vous avez mis à jour le serveur en version 4.1, mais omis
d'utiliser le script
mysql_fix_privilege_tables
pour élargir
la colonne Password
.
Si la colonne Password
est suffisamment
grande, elle peut stocker un mot de passe long ou court.
Dans ce cas, PASSWORD()
,
GRANT
et SET PASSWORD
vont générer des hashs longs, à moins que le serveur
n'ait été lancé avec l'option
--old-passwords
. Cette option force le
serveur à utiliser les hashs courts.
Le but de l'option --old-passwords
est
d'assurer la compatibilité ascendante avec les clients pre-4.1
clients dans certaines circonstances où le serveur aurait
généré des hashs longs. Cela n'affecte pas l'identification,
puisque les clients 4.1 peuvent continuer à utiliser les
comptes avec des hashs longs, mias cela empêche la création de
hash longs dans la table user
, lors de la
modification de mots de passe. Si cela arrive, le compte me
pourra plus être utilisé avec les clients pre-4.1. Sans
l'option --old-passwords
le scénario suivant
est possible :
Un ancient client se connecter sur un compte, avec un hash court.
Le client change le mot de passe. Sans l'option
--old-passwords
, cela conduit à la
création d'un hash long.
Lors de la prochaine connexion, le client pre-4.1 ne peut
plus se connecter, car le compte requiert désormais le
nouveau mécanisme d'identification. Une fois que le hash
long est dans la table user
, seuls les
clients 4.1 peuvent l'utiliser, car les clients pre-4.1 ne
le comprennent pas.
Ce scénario montre combien il est dangeureux d'utiliser un
serveur 4.1 sans l'option --old-passwords
si
vous devez supporter des clients pre-4.1. En utilisant l'option
--old-passwords
sur le serveur, les opérations
de modification de mots de passe ne génèrent pas de hashs
longs, et les utilisateurs ne se barreront pas l'accès par
inadvertence.
L'inconvénient de l'option --old-passwords
est
que tous les hashs que vous allez créer seront des hashs
courts, même pour les clients 4.1. Par conséquent, vous perdez
la sécurité améliorée que les hashs longs apportent. Si vous
voulez créer un compte avec un hash long (par exemple, pour un
client 4.1), il faudra le faire avec un serveur qui n'utilise
pas l'option --old-passwords
.
Les scénarios suivants sont possibles avec un serveur 4.1 :
Scenario 1 : Colonne
Password
courte dans la table
user
Seuls, les hashs courts peuvent être stockés dans la
colonne Password
.
Le serveur utilise uniquement les hashs courts pour les identifications.
Pour les clients connectés, la génération de mot de passe
avec PASSWORD()
, GRANT
ou SET PASSWORD
utilise les mots de passe
courts uniquement. Toute modification de compte entraine la
création d'un hash court.
L'option --old-passwords
peut être
utilisée, mais est superflue, car la colonne
Password
courte impose la manipulation de
hashs courts de toutes manières.
Scenario 2 : colonne
Password
longue dans la table
user
; serveur sans l'option
--old-passwords
les hashs courts et longs peuvent être stockés dans la
colonne Password
.
Les clients 4.1 peuvent s'identifier sur leur compte avec des hashs courts ou longs.
Les clients pre-4.1 peuvent s'identifier sur leur compte avec des hashs courts.
Pour les clients connectés, la génération de mot de passe
avec PASSWORD()
, GRANT
ou SET PASSWORD
utilise les mots de passe
longs uniquement. Toute modification de compte entraine la
création d'un hash long.
Comme indiqué précédemment, le danger de ce scénario est
qu'il est possible que les clients pre-4.1 se voient l'accès au
serveur barré. Toutes les modifications du compte avec
GRANT
, SET PASSWORD
et
PASSWORD()
conduisent à un hash long, qui
empêrchera les clients pre-4.1 d'utiliser ce compte.
Pour régler ce problème, vous pouvez modifier le mot de passe
d'une manière spéciale. Par exemple, normalement, vous pouvez
utiliser la commande SET PASSWORD
comme ceci
pour modifier un mot de passe :
mysql>SET PASSWORD FOR
->'some_user'@'some_host' = PASSWORD('mypass');
Pour changer le mot de passe avec un hash court, utilisez la
fonction OLD_PASSWORD()
:
mysql>SET PASSWORD FOR
->'some_user'@'some_host' = OLD_PASSWORD('mypass');
OLD_PASSWORD()
est pratique pour les
situations où vous voulez explicitement générer un hash
court.
Scenario 3 : colonne
Password
longue dans la table
user
; serveur avec l'option
--old-passwords
les hashs courts et longs peuvent être stockés dans la
colonne Password
.
Les clients 4.1 peuvent s'identifier sur leur compte avec
des hashs courts ou longs. Notez qu'il n'est alors possible
de créer des hashs longs si le serveur utilise
--old-passwords
).
Les clients pre-4.1 peuvent s'identifier sur leur compte avec des hashs courts.
Pour les clients connectés, la génération de mot de passe
avec PASSWORD()
, GRANT
ou SET PASSWORD
utilise les mots de passe
courts uniquement. Toute modification de compte entraine la
création d'un hash long.
Dans ce scénario, vous ne pouvez plus créer de compte avec un
hash long, car --old-passwords
l'empêche. De
même, si vous créez un compte avec un hash long sur un serveur
qui utilise l'option --old-passwords
, la
modification du mot de passe tant que
--old-passwords
est active, aura pour effet de
réduire la taille du hash, et vous perdre en sécurité.
Les inconvénients de ces scénario sont les suivants :
Scenario 1) vous ne pouvez pas tirer partie des hashs long et de leur sécurité accrue.
Scenario 2) Les comptes avec des mots de passe courts sont
inaccessibles aux clients pre-4.1 si vous modifiez leur mot de
passe sans utiliser la fonction
OLD_PASSWORD()
.
Scenario 3) --old-passwords
empêche les
comptes avec des hashs courts d'être barrés, mais les
opérations de modifications de mots de passe créeront des
hashs courts, et vous ne pourrez pas les modifier tant que à
--old-passwords
est effective.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.