Causes des erreurs Access denied
<<<
Hashage de mots de passe en MySQL 4.1 Administration du serveur
>>>

5.4 Règles de sécurité et droits d'accès au serveur MySQL
5 Administration du serveur
 Manuel de Référence MySQL 4.1 : Version Française

Rôle du système de privilèges
Comment fonctionne le système de droits
Droits fournis par MySQL
Se connecter au serveur MySQL
Contrôle d'accès, étape 1 : Vérification de la connexion
Contrôle d'accès, étape 2 : Vérification de la requête
Quand les modifications de privilèges prennent-ils effets ?
Causes des erreurs Access denied
->Hashage de mots de passe en MySQL 4.1

5.4.9 Hashage de mots de passe en MySQL 4.1

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.

Sommaire :

<< Hashage de mots de passe en MySQL 4.1 >>
Causes des erreurs Access denied Règles de sécurité et droits d'accès au serveur MySQL Administration du serveur