MySQL ユーザアカウントは、mysql
データベースの user
テーブルにリストアップされています。各 MySQL
アカウントにはパスワードが割り当てられますが、user
テーブルの Password
カラムに保存されるのは平文テキストのパスワードではなく、パスワードから計算されたハッシュ値です。パスワードハッシュ値は、PASSWORD()
関数によって計算されます。
MySQL は、クライアントとサーバ間通信の 2 つのフェーズでパスワードを使用します。
まず、クライアントがサーバに接続しようとするとき、初期認証ステップとして、クライアントはパスワードを提示する。このパスワードは、クライアントが使用を希望するアカウントの、ユーザテーブルに保存されたハッシュ値と一致している必要がある。
次に、クライアントが接続した後、クライアントは、user
テーブルに含まれているパスワードハッシュを設定または変更することができる(適切な権限がある場合)。このためには、クライアントは、PASSWORD()
関数を使用してパスワードハッシュを生成するか、GRANT
または SET PASSWORD
ステートメントを使用する。
つまり、クライアントが最初に接続しようとする際、サーバが認証するのにハッシュ値を使用します。接続したクライアントが
PASSWORD()
関数を実行したり、GRANT
または
SET PASSWORD
ステートメントを使用してパスワードの設定または変更を行うと、サーバがハッシュ値を生成します。
パスワードハッシュメカニズムは MySQL 4.1
で更新され、セキュリティが向上し、パスワード盗難の危険性が少なくなっています。
ただし、この新しいメカニズムは 4.1 サーバと
4.1
クライアントしか理解できないため、互換性の問題があります。
4.1
クライアントはパスワードハッシュの新旧メカニズムの両方を理解できるので、4.1
より前のサーバにでも接続できます。しかし、4.1
より前のクライアントが 4.1
サーバに接続しようとすると、問題が発生する可能性があります。たとえば、4.0
mysql
クライアントが 4.1
サーバに接続しようとすると、以下のエラーメッセージが表示される可能性があります。
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
以下、以前のパスワードメカニズムと新しいパスワードメカニズムとの違い、およびサーバを 4.1 にアップグレードしたときに 4.1 より前のクライアントと互換性を保つ方法について説明します。
注意: ここでの説明は 4.1 とそれ以前の動作を対比するものですが、ここで説明する 4.1 の動作は実際には 4.1.1 からのものです。MySQL 4.1.0 の動作は、4.1.1 以降で導入されたメカニズムと少し異なります。4.1.0 とそれ以降のバージョンとの違いについては、後で説明します。
MySQL 4.1 より前は、PASSWORD()
関数によって計算されるパスワードハッシュは
16 バイト長でした。次に例を示します。
mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e |
+--------------------+
MySQL 4.1 より前は、user
テーブルの
Password
カラム(ハッシュが保存される場所)も 16
バイト長でした。
MySQL 4.1 から、PASSWORD()
関数が、より長い 41
バイトのハッシュ値を生成するようになっています。
mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass') |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+
したがって、この長さの値を保存するため、user
テーブルの Password
カラムも 41
バイト長であることが必要です。
MySQL 4.1
の新規インストールを実行すると、Password
カラムは自動的に 41 バイト長になる。
旧バージョンを 4.1
にアップグレードした場合、mysql_fix_privilege_tables
スクリプトを実行して Password
カラムを 16 バイト長から 41
バイト長に変更する必要がある。このスクリプトは既存のパスワード値を変更しない。既存のものは
16 バイト長のままである。
拡張された Password
カラムは、新旧どちらの形式のパスワードハッシュも保存できます。与えられたパスワードハッシュ値の形式は次の
2 つの違いにより判断されます。
16 バイトと 41 バイトという長さ自体が違う。
2
つ目の違いとしては、新しい形式のパスワードハッシュは常に
‘*
’
文字で始まり、旧形式のパスワードはそれ以外の文字で始まる。
長いパスワードハッシュ形式の方が暗号化の面で優れており、クライアント認証において旧形式の短いハッシュよりもセキュリティが高いと言えます。
パスワードハッシュの長短の違いは、認証時にサーバがパスワードを使用する方法と、パスワードを変更する接続クライアントに対してサーバがパスワードハッシュを生成する方法に関係してきます。
認証時にサーバがパスワードを使用する方法は、Password
カラムの幅により次のような影響を受けます。
カラムが短い場合、短いハッシュ認証だけが使用される。
カラムが長い場合、長短のハッシュどちらでも保存でき、サーバはどちらの形式でも使用できる。
4.1 より前のクライアントは接続はできても、旧ハッシュメカニズムしか理解できないため、短いハッシュのアカウントしか認証できない。
4.1 クライアントは、長短どちらのハッシュのアカウントでも認証できる。
短いハッシュのアカウントでも、4.1 クライアントの方が旧クライアントよりも認証プロセスのセキュリティが少し向上しています。認証のセキュリティは以下の順で高くなります。
短いパスワードハッシュのアカウントに対する 4.1 より前のクライアント認証
短いパスワードハッシュのアカウントに対する 4.1 クライアント認証
長いパスワードハッシュのアカウントに対する 4.1 クライアント認証
接続クライアントに対してサーバがパスワードハッシュを生成する方法は、Password
カラムの幅と --old-passwords
オプションにより影響を受けます。4.1
サーバは、次の条件が満たされた場合だけ、長いハッシュを生成します。
Password
カラムが長いハッシュ値を保存できる長さであること、および
--old-passwords
オプションが指定されていないことが必要です。
これらの条件は以下のように適用されます。
Password
カラムが長いハッシュを保存できる長さ(41
バイト)であること。
カラムが更新されておらず、4.1
より前の長さ(16
バイト)のままだと、クライアントが
PASSWORD()
、GRANT
、または
SET PASSWORD
を使用してパスワード変更操作を行ったとき、長いハッシュが収まらないことをサーバが認識し、短いハッシュを生成する
(4.1
にアップグレードしたが、mysql_fix_privilege_tables
スクリプトを実行せず、Password
カラムが長くなっていない場合にこのようになる)。
Password
カラムが長ければ、長短どちらのパスワードハッシュも保存できる。この場合、サーバが
--old-passwords
オプションで起動されていなければ、PASSWORD()
、GRANT
、および
SET PASSWORD
により長いハッシュが生成される。
このオプションが指定されていると、強制的に短いパスワードハッシュが生成される。
--old-passwords
オプションの目的は、サーバが長いパスワードハッシュを生成する環境において、4.1
より前のクライアントと下位互換性を保てるようにすることです。これは認証には影響しませんが(4.1
クライアントは長いパスワードハッシュのアカウントを使用できる)、パスワード変更操作の結果として
user
テーブルで長いパスワードハッシュが生成されることを防ぎます。長いパスワードハッシュが生成されると、そのアカウントは
4.1
より前のクライアントでは使用できなくなります。--old-passwords
オプションを指定しない場合、以下のシナリオが想定されます。
旧クライアントが、短いパスワードハッシュのアカウントに接続する。
クライアントがアカウントのパスワードを変更する。--old-passwords
が指定されていない場合、アカウントに対して長いパスワードハッシュが生成される。
次回、旧クライアントがこのアカウントに接続しようとしても、認証時にアカウントが新規ハッシュメカニズムを必要とするため、接続できない。user
テーブルでアカウントに対して長いパスワードハッシュが生成された場合、4.1
クライアントのみそれを認証できる。4.1
より前のクライアントでは長いハッシュを理解できない。
このシナリオでは、4.1
より前の旧クライアントをサポートする必要がある場合、--old-passwords
オプションを使用せずに 4.1
サーバを起動するのは危険であることを示しています。--old-passwords
を指定してサーバを起動することにより、パスワード変更操作を行っても長いパスワードハッシュは生成されません。したがって、旧クライアントがアカウントにアクセスできなくなることがありません(旧クライアントが、パスワード変更時、偶発的に長いパスワードハッシュを生成して自らをロックアウトすることはありません)。
--old-passwords
オプションの欠点は、4.1
クライアントでも、パスワード作成または変更時に短いハッシュを使用するということです。そのため、長いパスワードハッシュによる高いセキュリティを活用できません。4.1
クライアント用などに長いハッシュのアカウントを作成したい場合には、--old-passwords
なしでサーバを実行する必要があります。
4.1 サーバの実行には以下のシナリオが想定されます。
シナリオ 1. user テーブルの短い
Password
カラム
Password
カラムには短いハッシュのみ保存できる。
サーバはクライアント認証時、短いハッシュだけを使用する。
接続クライアントは、PASSWORD()
、GRANT
、または
SET PASSWORD
を使用するパスワードハッシュ生成操作で短いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず短いパスワードハッシュになる。
--old-passwords
オプションは使用できるが、意味がない。短い
Password
カラムでは、サーバは短いパスワードハッシュしか生成しない。
シナリオ 2. 長い Password
カラム、サーバを --old-passwords
オプションなしで起動
Password
カラムには長短いずれのハッシュも保存できる。
4.1 クライアントは、長短どちらのハッシュのアカウントでも認証できる。
4.1 より前のクライアントは、短いハッシュのアカウントのみ認証できる。
接続クライアントは、PASSWORD()
、GRANT
、または
SET PASSWORD
を使用するパスワードハッシュ生成操作で長いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず長いパスワードハッシュになる。
OLD_PASSWORD()
を使用して、明示的に短いハッシュを生成するようにできる。たとえば、アカウントに短いパスワードを割り当てるには、以下のように
UPDATE
を使用する。
mysql>UPDATE user SET Password = OLD_PASSWORD('mypass')
->WHERE Host = 'some_host' AND User = 'some_user';
mysql>FLUSH PRIVILEGES;
上述したように、このシナリオでは、短いパスワードハッシュのアカウントに、4.1
より前のクライアントがアクセスできなくなる危険性があります。GRANT
、SET
PASSWORD
、または PASSWORD()
を使用してアカウントのパスワードを変更すると、新規パスワードハッシュが長くなるため、4.1
より前のクライアントは、4.1
にアップグレードしないとそのアカウントを認証できなくなります。
シナリオ 3. 長い Password
カラム、サーバを --old-passwords
オプションで起動
Password
カラムには長短いずれのハッシュも保存できる。
4.1
クライアントは長短いずれのハッシュのアカウントでも認証できる(注意:
長いハッシュの作成は、サーバを
--old-passwords
なしで起動したときだけ可能)。
4.1 より前のクライアントは、短いハッシュのアカウントのみ認証できる。
接続クライアントは、PASSWORD()
、GRANT
、または
SET PASSWORD
を使用するパスワードハッシュ生成操作で短いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず短いパスワードハッシュになる。
このシナリオでは、--old-passwords
によって長いハッシュが生成されないため、長いパスワードハッシュのアカウントを作成できません。また、--old-passwords
オプションを使用する前に長いハッシュのアカウントを作成した場合でも、--old-passwords
の有効時にアカウントのパスワードを変更すると短いパスワードになってしまうので、長いハッシュが持つセキュリティ上の利点が失われます。
これらのシナリオの欠点はそれぞれ以下のように要約できます。
シナリオ 1. セキュリティの高い認証を提供する長いハッシュを活用できない。
シナリオ 2. OLD_PASSWORD()
を使用せずにパスワードを変更すると、短いハッシュのアカウントに
4.1
より前のクライアントがアクセスできなくなる。
シナリオ 3. --old-passwords
によって、短いハッシュのアカウントがアクセス不能になることは防がれるが、長いハッシュをパスワード変更すると短いハッシュになってしまい、--old-passwords
が有効な間はそれを元の長さに戻せない。
アプリケーションプログラムに対するパスワードハッシュ変更の影響
MySQL 4.1 にアップグレードすると、独自の目的で
PASSWORD()
を使用してパスワードを生成するアプリケーションとの互換性に問題が生じます。本来、PASSWORD()
は MySQL
ユーザのパスワード管理専用なので、アプリケーションでこれを実行すべきではありません。しかし現状では、いくつかのアプリケーションが独自の目的で
PASSWORD()
を使用しています。4.1
にアップグレードし、長いパスワードハッシュが生成される状態でサーバを実行すると、独自の目的で
PASSWORD()
を使用するアプリケーションは壊れます。推奨される対処法は、アプリケーションを修正して
SHA1()
または MD5()
など、別の関数を使用してハッシュ値を生成するように設定することです。
それが可能でなければ、OLD_PASSWORD()
関数を使用することができます。これは、旧形式の短いハッシュを生成するためのものです(注意:
ただし、OLD_PASSWORD()
は将来サポートされなくなる可能性があります)。
短いハッシュを生成する状態でサーバが実行中の場合、OLD_PASSWORD()
は利用可能ですが、PASSWORD()
と同じになります。
MySQL 4.1.0 のパスワードハッシュは 4.1.1 以降のパスワードハッシュと異なります。 4.1.0 の違いは以下のとおりです。
パスワードハッシュは 41 バイトではなく、45 バイト長である。
PASSWORD()
関数は繰り返し不可。つまり、特定の引数
X
で、連続して
PASSWORD(X)
を呼び出すと異なる結果が生成される。
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.