【PHP8.x】CRYPT_EXT_DES定数の使い方
CRYPT_EXT_DES定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
CRYPT_EXT_DES定数は、PHPのcrypt()関数において、拡張DESアルゴリズムに基づいて文字列をハッシュ化する方式を指定するために使用される定数です。この定数をcrypt()関数の第2引数(ソルト)に含めることで、入力された文字列(例えばパスワード)が拡張DES形式で一方向ハッシュに変換されます。
拡張DESアルゴリズムは、標準的なDESアルゴリズムをベースにしつつ、より長いソルト(ハッシュ化の際に元の文字列に付加されるランダムなデータ)を利用することで、セキュリティ強度を高めています。具体的には、ソルト文字列はアンダースコア(_)と大文字から始まる11文字の形式を取ります。このハッシュ形式は、特にUnix系のオペレーティングシステムにおいて、ユーザーパスワードの格納などで広く採用されてきました。
システムエンジニアを目指す方にとって、パスワードなどの機密情報を安全に扱うためのハッシュ化は重要な概念です。ただし、現代のセキュリティ基準では、CRYPT_BLOWFISHやCRYPT_ARGON2IDといった、より強力で計算コストの高いハッシュアルゴリズムの使用が一般的に推奨されています。CRYPT_EXT_DESは、既存のシステムとの互換性を維持する必要がある場合などに利用されることがありますが、新規開発においてはより現代的なアルゴリズムの選択を検討することが望ましいでしょう。
構文(syntax)
1<?php 2$password = 'secret'; 3$salt = CRYPT_EXT_DES; 4$hashed_password = crypt($password, $salt); 5echo $hashed_password; 6?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
CRYPT_EXT_DES は、DES暗号化アルゴリズムが利用可能であることを示す整数値です。この定数が定義されている場合、PHPでDES暗号化関数を使用できます。
サンプルコード
PHP Crypt Extended DES ハッシュ化を実演する
1<?php 2 3/** 4 * CRYPT_EXT_DES 定数を使用して Extended DES ハッシュアルゴリズムによるハッシュ化を実演します。 5 * 6 * crypt() 関数は一方向のハッシュを生成するために使用されます。 7 * これは復号化(元の文字列に戻すこと)はできません。 8 * 主にパスワードの安全な保存と検証のために利用されます。 9 * 10 * @param string $password ハッシュ化する文字列。 11 * @return string ハッシュ化された文字列を返します。CRYPT_EXT_DES がサポートされていない場合は空文字列を返します。 12 */ 13function demonstrateExtendedDesHashing(string $password): string 14{ 15 // CRYPT_EXT_DES 定数が定義されているか、かつその値がtrue(サポートされている)かを確認します。 16 // Extended DES は、Unix系のシステムでサポートされている可能性のある古いハッシュアルゴリズムの一つです。 17 if (!defined('CRYPT_EXT_DES') || !CRYPT_EXT_DES) { 18 echo "エラー: Extended DES ハッシュアルゴリズム (CRYPT_EXT_DES) はこのシステムでサポートされていません。\n"; 19 return ''; 20 } 21 22 // Extended DES アルゴリズム用のソルトを生成します。 23 // Extended DES のソルトは '_' で始まり、合計9文字のランダムな文字列です。 24 // ソルトはハッシュごとにユニークであるべきであり、セキュリティを向上させます。 25 $saltCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 26 $salt = '_'; // Extended DES ソルトのプレフィックス 27 for ($i = 0; $i < 8; $i++) { 28 // 安全な乱数生成器を使用します。 29 $salt .= $saltCharacters[random_int(0, strlen($saltCharacters) - 1)]; 30 } 31 32 // crypt() 関数を使用してパスワードをハッシュ化します。 33 // 第1引数にハッシュ化する文字列、第2引数にソルトを渡します。 34 $hashedPassword = crypt($password, $salt); 35 36 echo "元のパスワード: " . $password . "\n"; 37 echo "Extended DES 用に生成されたソルト: " . $salt . "\n"; 38 echo "ハッシュ化されたパスワード (Extended DES): " . $hashedPassword . "\n\n"; 39 40 return $hashedPassword; 41} 42 43// --- サンプルコードの実行 --- 44 45// 1. パスワードをハッシュ化する例 46$userPassword = 'mySecurePassword123'; 47$storedHash = demonstrateExtendedDesHashing($userPassword); 48 49// 2. ハッシュ化されたパスワードを検証する例 50// 実際のアプリケーションでは、$storedHash はデータベースなどから取得されます。 51// 検証には、元のハッシュに使用されたソルトを再利用する必要があります。 52if (!empty($storedHash)) { 53 echo "--- パスワード検証の例 ---\n"; 54 $passwordAttempt = 'mySecurePassword123'; // 検証のためにユーザーが入力したパスワード 55 56 // Extended DES のハッシュの場合、最初の9文字がソルトです。 57 $saltFromStoredHash = substr($storedHash, 0, 9); 58 59 // ユーザーが入力したパスワードを、保存されているハッシュと同じソルトで再度ハッシュ化します。 60 $hashedAttempt = crypt($passwordAttempt, $saltFromStoredHash); 61 62 echo "検証しようとしているパスワード: " . $passwordAttempt . "\n"; 63 echo "保存されたハッシュから抽出したソルト: " . $saltFromStoredHash . "\n"; 64 echo "検証のためにハッシュ化されたパスワード: " . $hashedAttempt . "\n"; 65 echo "保存されていたハッシュ: " . $storedHash . "\n"; 66 67 // 新しく生成されたハッシュと保存されているハッシュを比較します。 68 // ハッシュが一致すればパスワードは正しいと判断できます。 69 if ($hashedAttempt === $storedHash) { 70 echo "結果: パスワードは一致しました。\n"; 71 } else { 72 echo "結果: パスワードは一致しませんでした。\n"; 73 } 74 75 // 間違ったパスワードでの検証例 76 echo "\n--- 間違ったパスワードでの検証例 ---\n"; 77 $wrongPasswordAttempt = 'wrongPassword'; 78 $hashedWrongAttempt = crypt($wrongPasswordAttempt, $saltFromStoredHash); 79 echo "間違ったパスワードでの試行: " . $wrongPasswordAttempt . "\n"; 80 echo "ハッシュ化された試行: " . $hashedWrongAttempt . "\n"; 81 if ($hashedWrongAttempt === $storedHash) { 82 echo "結果: (誤って) パスワードは一致しました。\n"; 83 } else { 84 echo "結果: パスワードは一致しませんでした。(正しい結果)\n"; 85 } 86} 87 88?>
このPHPコードは、CRYPT_EXT_DES定数を利用して、crypt()関数によるExtended DESハッシュアルゴリズムでのパスワードハッシュ化とその検証方法を実演しています。
crypt()関数は、与えられた文字列(パスワードなど)を一方向のハッシュ値に変換します。これは元の文字列に戻す「復号」ができない特性を持っており、パスワードを安全に保存し、その正当性を確認するために利用されます。
CRYPT_EXT_DES定数は、システムがExtended DESハッシュアルゴリズムをサポートしているかを示す整数値です。コードではまずこの定数が定義され、かつ利用可能であるかを確認しています。サポートされていない場合、このアルゴリズムでのハッシュ化は行えません。
パスワードをハッシュ化する際、セキュリティを向上させるために「ソルト」と呼ばれるランダムな文字列を付加します。Extended DESアルゴリズムでは、ソルトはアンダースコア(_)で始まり、その後に続く8文字と合わせて合計9文字となります。このソルトはハッシュごとにユニークであるべきです。
demonstrateExtendedDesHashing関数は、引数としてハッシュ化したい$password文字列を受け取ります。内部でExtended DES用のソルトを生成し、crypt()関数を使ってパスワードとソルトからハッシュ値を計算して返します。もしCRYPT_EXT_DESがサポートされていない場合は空文字列を返します。
パスワードの検証は、ユーザーが入力したパスワードと、データベースなどに保存されている元のハッシュ値から抽出したソルト(Extended DESの場合、保存されたハッシュ値の冒頭9文字がソルトです)を使って再度ハッシュ化を行い、その結果が保存されているハッシュ値と一致するかを比較することで行います。両者が一致すれば、パスワードは正しいと判断できます。
CRYPT_EXT_DES定数は、古いハッシュアルゴリズムであるExtended DESを示します。このアルゴリズムは現在ではセキュリティ上の懸念があるため、新規システムでのパスワードハッシュ化には推奨されません。より堅牢なセキュリティのためには、PHP 5.5以降で提供されているpassword_hash()関数を使用し、PASSWORD_BCRYPTやPASSWORD_ARGON2IDといった現代的で強力なアルゴリズムを選択することが強く推奨されます。
crypt()関数によるハッシュ化は「一方向」の処理であり、一度ハッシュ化されたパスワードを元の状態に戻す「復号」は原理的にできません。これはパスワードをデータベースなどに安全に保存するための基本的なセキュリティ原則です。
ソルトはパスワードごとに異なるランダムな文字列を生成し、ハッシュ値と一緒に保存することが必須です。これにより、辞書攻撃やレインボーテーブル攻撃に対する耐性が向上します。サンプルコードのようにソルトを自分で生成する際には、アルゴリズムに合った形式を守る必要があります。また、CRYPT_EXT_DESがシステムでサポートされているか、defined()関数と定数の値で確認する処理は良い習慣です。
PHP crypt関数でExtended DESハッシュ化する
1<?php 2 3/** 4 * Extended DES ハッシュアルゴリズムを使ってパスワードをハッシュ化します。 5 * 6 * この関数は、PHPの crypt() 関数と CRYPT_EXT_DES 定数を利用して、 7 * Extended DES ハッシュアルゴリズムによるパスワードのハッシュ化を実演します。 8 * CRYPT_EXT_DES 定数は、Extended DES ハッシュが利用可能であることを示します。 9 * 10 * @param string $password ハッシュ化する元のパスワード。 11 * @return string|null ハッシュ化されたパスワード。Extended DESが利用できない場合や、 12 * ハッシュ化に失敗した場合は null を返します。 13 */ 14function hashPasswordWithExtDes(string $password): ?string 15{ 16 // CRYPT_EXT_DES 定数が定義されており、かつその値が0以外であるかを確認します。 17 // これは、システムがExtended DESハッシュアルゴリズムをサポートしているかを示します。 18 // PHPのビルド設定によっては、特定のハッシュアルゴリズムが利用できない場合があります。 19 if (!defined('CRYPT_EXT_DES') || !CRYPT_EXT_DES) { 20 echo "Warning: Extended DES hashing is not available on this system. Cannot proceed.\n"; 21 return null; 22 } 23 24 // Extended DES ハッシュ用のランダムなソルトを生成します。 25 // crypt() 関数は、ソルトの形式から使用するハッシュアルゴリズムを自動的に判別します。 26 // Extended DES のソルトは '_', 8文字のランダムな英数字, '_' の形式である必要があります。 27 $saltChars = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 28 $salt = ''; 29 for ($i = 0; $i < 8; $i++) { 30 // random_int() は安全な乱数を生成するために推奨されます。 31 $salt .= $saltChars[random_int(0, strlen($saltChars) - 1)]; 32 } 33 $extDesSalt = '_' . $salt . '_'; 34 35 // crypt() 関数を使ってパスワードをハッシュ化します。 36 // 第1引数に元のパスワード、第2引数に生成したソルトを渡します。 37 $hashedPassword = crypt($password, $extDesSalt); 38 39 // ハッシュ化が失敗した場合、crypt() は通常、false または '*0' / '*1' の文字列を返します。 40 // この場合、アルゴリズムがサポートされていないか、ソルトが無効である可能性があります。 41 if ($hashedPassword === false || str_starts_with($hashedPassword, '*')) { 42 echo "Error: Failed to hash password using Extended DES (possibly unsupported algorithm or invalid salt).\n"; 43 return null; 44 } 45 46 return $hashedPassword; 47} 48 49// --- サンプルコードの実行 --- 50 51// ハッシュ化したい元のパスワード 52$plainPassword = 'MySecretPassword123'; 53 54echo "元のパスワード: " . $plainPassword . "\n\n"; 55 56// パスワードをハッシュ化 57$hashedPassword = hashPasswordWithExtDes($plainPassword); 58 59if ($hashedPassword !== null) { 60 echo "ハッシュ化されたパスワード (Extended DES): " . $hashedPassword . "\n\n"; 61 62 // --- ハッシュ化されたパスワードの検証 --- 63 // crypt() 関数は、既存のハッシュをソルトとして渡すことで、 64 // 新しく入力されたパスワードがそのハッシュと一致するかを検証できます。 65 // hash_equals() 関数は、タイミング攻撃を防ぐために文字列の比較に推奨される関数です。 66 67 echo "--- パスワード検証 --- \n"; 68 69 // 1. 正しいパスワードで検証 70 if (hash_equals($hashedPassword, crypt($plainPassword, $hashedPassword))) { 71 echo "✅ 元のパスワードで検証に成功しました。\n"; 72 } else { 73 echo "❌ 元のパスワードで検証に失敗しました。\n"; 74 } 75 76 // 2. 間違ったパスワードで検証 77 $wrongPassword = 'WrongPassword456'; 78 if (hash_equals($hashedPassword, crypt($wrongPassword, $hashedPassword))) { 79 echo "❌ 誤ったパスワード「" . $wrongPassword . "」で検証に成功してしまいました (これは通常起こりません)。\n"; 80 } else { 81 echo "✅ 誤ったパスワード「" . $wrongPassword . "」で検証に失敗しました。\n"; 82 } 83} 84 85?>
このPHPサンプルコードは、パスワードをExtended DESアルゴリズムでハッシュ化する方法を実演しています。まず、CRYPT_EXT_DESという定数を用いて、現在のシステムがExtended DESハッシュアルゴリズムをサポートしているかを確認します。この定数が定義されており、かつ0以外の値である場合に、アルゴリズムが利用可能であることを示します。
hashPasswordWithExtDes関数は、ハッシュ化したい元のパスワード($password)を文字列として引数に受け取ります。関数内部では、Extended DESに特有の形式である、アンダースコア(_)で囲まれた8文字のランダムな英数字から成るソルトを生成します。その後、PHPのcrypt()関数を使用し、生成したソルトと元のパスワードを組み合わせてハッシュ化を実行します。crypt()関数は、渡されたソルトの形式から適切なハッシュアルゴリズムを自動的に判別して適用します。ハッシュ化が成功した場合、結果としてハッシュ化されたパスワード文字列を返却し、失敗した場合はnullを返します。
生成されたハッシュ化パスワードの検証では、既存のハッシュ化パスワードをcrypt()関数のソルトとして再度使用し、入力されたパスワードがそのハッシュと一致するかを確認します。この際、セキュリティを考慮し、文字列の比較にはタイミング攻撃を防ぐhash_equals()関数を用いることが推奨されます。この一連のプロセスを通じて、パスワードの安全なハッシュ化と検証の基礎を学ぶことができます。
このサンプルコードは、Extended DESハッシュアルゴリズムを用いてパスワードをハッシュ化する方法を示しています。まず、CRYPT_EXT_DES定数がシステムで定義され、かつサポートされているかを確認することが重要です。crypt()関数は与えられたソルトの形式から使用するハッシュアルゴリズムを自動的に判別するため、Extended DES用のソルト形式(_で囲まれた8文字のランダムな英数字)を正確に生成する必要があります。ソルトにはrandom_int()のような安全な乱数生成関数を使用してください。ハッシュ化されたパスワードの検証には、タイミング攻撃を防ぐためにhash_equals()関数を使用することが推奨されます。ただし、Extended DESは現在では古いアルゴリズムであり、より強力なセキュリティを提供するpassword_hash()関数とpassword_verify()関数の利用が現代のPHPでは一般的に推奨されます。本サンプルコードは、その仕組みを理解するための参考としてください。