【PHP8.x】CRYPT_SHA512定数の使い方
CRYPT_SHA512定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
CRYPT_SHA512定数は、PHPの標準関数であるcrypt()関数において、指定された文字列(主にパスワード)をSHA-512ハッシュアルゴリズムを用いてハッシュ化する際に、そのアルゴリズムを選択するために使用される特別な値を表す定数です。
SHA-512は、セキュアハッシュアルゴリズム(Secure Hash Algorithm)ファミリーの一つであり、入力された任意の長さのデータから、予測不可能な固定長(この場合は512ビット)のハッシュ値を生成します。このアルゴリズムは、非常に強力な暗号学的ハッシュ関数として知られており、生成されるハッシュ値の衝突耐性が高く、元のデータを効率的に復元することが極めて困難であるという特性を持っています。CRYPT_SHA512定数を利用することで、crypt()関数は、ソルトと呼ばれるランダムな文字列と組み合わせ、入力文字列のハッシュ値をSHA-512形式で計算します。
この定数をcrypt()関数で使用する際には、第二引数であるソルト文字列に$6$で始まる形式の文字列を含める必要があります。この$6$は、続く文字列がSHA-512アルゴリズム用のソルトであることを示し、これによりcrypt()関数が正しいハッシュ化方式を適用できるようになります。ソルトは、レインボーテーブル攻撃などのパスワード解析手法からハッシュを保護するために不可欠な要素であり、異なるソルトを使用することで、同じパスワードからでも異なるハッシュ値が生成され、セキュリティが大幅に向上します。
システムエンジニアを目指す皆様にとって、パスワードの安全な管理は非常に重要な知識です。このCRYPT_SHA512定数は、PHPのcrypt()関数を用いたハッシュ化の具体的な選択肢の一つとして理解しておきましょう。ただし、現代のPHPアプリケーションでは、より安全で柔軟なpassword_hash()およびpassword_verify()関数ファミリーを使用することが一般的に推奨されています。これらはソルトの自動生成やストレッチングといったセキュリティ対策を内部で自動的に処理するため、より安全かつ簡単にパスワードハッシュを実装できます。CRYPT_SHA512は、特定のレガシーシステムや互換性の要件がある場合に使用されることが多い定数であることも理解しておくと良いでしょう。
構文(syntax)
1<?php 2if (CRYPT_SHA512) { 3 $salt = '$6$rounds=5000$yoursaltstring$'; 4 $hashedPassword = crypt('password', $salt); 5} 6?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
CRYPT_SHA512は、SHA-512アルゴリズムを使用する暗号化手法を表す整数定数です。
サンプルコード
PHP Crypt SHA512でパスワードをハッシュ化・検証する
1<?php 2 3// このファイルは単体で動作します。 4 5/** 6 * SHA512アルゴリズムを使用してパスワードをハッシュ化します。 7 * 8 * CRYPT_SHA512定数は、PHPがSHA512ハッシュアルゴリズムをサポートしていることを示す整数値です。 9 * crypt() 関数は、ソルトに "$6$" プレフィックスが指定された場合に、この定数によって示される 10 * SHA512アルゴリズムを内部的に使用します。 11 * 12 * @param string $password ハッシュ化する元のパスワード。 13 * @return string|false ハッシュ化されたパスワード文字列、またはシステムがSHA512をサポートしない場合はfalse。 14 */ 15function hashPasswordWithSha512(string $password): string|false 16{ 17 // CRYPT_SHA512定数が定義されていて、その値が1であればSHA512がサポートされています。 18 // (通常、サポートされていれば1です。定義されていないか、0であればサポート外。) 19 if (!defined('CRYPT_SHA512') || CRYPT_SHA512 !== 1) { 20 echo "エラー: システムで CRYPT_SHA512 アルゴリズムがサポートされていません。\n"; 21 return false; 22 } 23 24 // SHA512用のソルトを生成します。 25 // ソルトは "$6$" で始まり、その後にランダムな16文字が続きます。 26 // random_bytes() はセキュアなランダムバイトを生成します。 27 // base64_encode() で文字列にし、不要な文字を安全な文字に置き換え、16文字にトリムします。 28 $saltPrefix = '$6$'; 29 $randomBytes = random_bytes(12); // 12バイトあればbase64で16文字以上生成可能 30 // base64_encodeは '+', '/' を含む可能性があり、これらはcryptのソルトでは推奨されないため、 31 // それぞれ '.' と '_' に置き換えるのが一般的です。 32 $randomString = substr(str_replace(['+', '/'], ['.', '_'], base64_encode($randomBytes)), 0, 16); 33 $salt = $saltPrefix . $randomString; 34 35 // crypt() 関数を使用してパスワードをハッシュ化します。 36 // 第二引数にソルトを指定することで、crypt() はソルトのプレフィックス($6$)を認識し、 37 // 自動的にSHA512アルゴリズムを選択します。 38 $hashedPassword = crypt($password, $salt); 39 40 return $hashedPassword; 41} 42 43/** 44 * 入力されたパスワードが既存のハッシュと一致するか検証します。 45 * 46 * @param string $password 検証するパスワード。 47 * @param string $existingHash 比較対象の既存のハッシュ(ソルト情報を含む)。 48 * @return bool パスワードが既存ハッシュと一致すればtrue、そうでなければfalse。 49 */ 50function verifyPasswordSha512(string $password, string $existingHash): bool 51{ 52 // crypt() 関数は、提供された既存ハッシュからソルトとアルゴリズム(この場合はSHA512)を自動的に抽出し、 53 // 入力パスワードを同じ条件でハッシュ化します。 54 $rehashedPassword = crypt($password, $existingHash); 55 56 // 再ハッシュ化されたパスワードと既存ハッシュを比較します。 57 // hash_equals() を使用することで、時間攻撃(timing attack)のリスクを軽減し、より安全に比較できます。 58 return hash_equals($rehashedPassword, $existingHash); 59} 60 61// --- サンプル使用例 --- 62 63$originalPassword = "SecurePassword123!"; 64 65echo "元のパスワード: " . $originalPassword . PHP_EOL . PHP_EOL; 66 67// パスワードをハッシュ化 68$hashed = hashPasswordWithSha512($originalPassword); 69 70if ($hashed !== false) { 71 echo "SHA512でハッシュ化されたパスワード: " . $hashed . PHP_EOL . PHP_EOL; 72 73 // 正しいパスワードで検証 74 echo "正しいパスワードで検証中..." . PHP_EOL; 75 if (verifyPasswordSha512($originalPassword, $hashed)) { 76 echo "検証成功: パスワードは一致します。" . PHP_EOL; 77 } else { 78 echo "検証失敗: パスワードは一致しません。 (これはエラーです)" . PHP_EOL; 79 } 80 81 echo PHP_EOL; 82 83 // 間違ったパスワードで検証 84 $wrongPassword = "WrongPassword!"; 85 echo "間違ったパスワード ('" . $wrongPassword . "') で検証中..." . PHP_EOL; 86 if (verifyPasswordSha512($wrongPassword, $hashed)) { 87 echo "検証成功: パスワードは一致します。(これはエラーです)" . PHP_EOL; 88 } else { 89 echo "検証失敗: パスワードは一致しません。(これは正しい結果です)" . PHP_EOL; 90 } 91} 92
PHP 8におけるCRYPT_SHA512定数は、システムがSHA512ハッシュアルゴリズムをサポートしているかを示す整数値です。この定数自体を直接ハッシュ化に使うのではなく、crypt()関数がソルトのプレフィックス($6$)を見てSHA512アルゴリズムを使用する際、内部的にこの定数の値でサポート状況を確認します。
hashPasswordWithSha512関数は、入力された$passwordをSHA512アルゴリズムでハッシュ化します。この関数はまずCRYPT_SHA512が利用可能かを確認し、利用できない場合はfalseを返します。次に、セキュリティを高めるためのランダムな文字列である「ソルト」を生成します。ソルトは$6$というプレフィックスを持ち、crypt()関数の第二引数に渡されることで、パスワードとソルトを基にハッシュ化された文字列を生成し、返します。
verifyPasswordSha512関数は、入力された$passwordが、保存されている$existingHashと一致するかを検証します。crypt()関数にパスワードと既存ハッシュを渡すと、既存ハッシュに含まれるソルトとアルゴリズム(SHA512)が自動的に抽出され、入力パスワードが同じ条件で再ハッシュ化されます。その後、再ハッシュ化された値と既存ハッシュをhash_equals()関数で安全に比較し、一致すればtrueを、そうでなければfalseを返します。これらの関数は、ユーザーのパスワードを安全に保存し、ログイン時の認証などに利用されます。
CRYPT_SHA512定数は、PHPがSHA512ハッシュアルゴリズムをサポートしているかを確認するために使用されます。利用前には、この定数が定義されており、値が1であることを必ず確認してください。 crypt()関数でSHA512ハッシュを行う際は、ソルト文字列の先頭に「$6$」プレフィックスを付けることが必須です。ソルトはrandom_bytes()関数を用いてセキュアに生成し、各パスワードに異なるものを使い、予測不能性を高めてください。また、ソルトに推奨されない文字(例: '+'や'/')が含まれないよう、適切に変換することが重要です。 パスワードの検証時には、再ハッシュ化されたパスワードと保存されているハッシュを比較する際に、必ずhash_equals()関数を使用してください。これにより、時間攻撃のリスクを低減し、より安全な比較が可能になります。