【PHP8.x】crypt関数の使い方

作成日: 更新日:

『crypt関数は、与えられた文字列を元に、一方向性のハッシュ文字列を生成する関数です。この関数は主に、ユーザーのパスワードをデータベースなどに安全に保存する目的で使用されます。第一引数にハッシュ化したい文字列、第二引数に「ソルト」と呼ばれる文字列を指定します。ソルトはハッシュ化のプロセスに影響を与える文字列で、同じパスワードであってもソルトが異なれば全く異なるハッシュ値が生成されるため、セキュリティを向上させる重要な役割を担います。生成されたハッシュ値から元の文字列を復元することは計算上非常に困難であり、このような性質を「一方向性」と呼びます。しかし、この関数は歴史的な経緯から複数のハッシュアルゴリズムをサポートしており、その中には現在では強度が不十分とされる古いアルゴリズムも含まれています。そのため、新規のアプリケーション開発においてパスワードをハッシュ化する際には、より安全で強力なハッシュを簡単に生成できるpassword_hash()関数と、それを検証するpassword_verify()関数の使用が強く推奨されています。

基本的な使い方

構文(syntax)

crypt(string $string, string $salt): string

引数(parameters)

string $string, string $salt

  • string $string: ハッシュ化したい文字列
  • string $salt: ハッシュ化に使用するソルト文字列

戻り値(return)

string

crypt関数は、指定された文字列を、指定されたソルトとアルゴリズムを用いて暗号化した結果を文字列で返します。

サンプルコード

PHP8 crypt関数で文字列を安全にハッシュ化・検証する

<?php

/**
 * crypt() 関数を使用して文字列をハッシュ化し、検証するサンプルコード。
 *
 * crypt() 関数は、一方向のハッシュ化アルゴリズムを適用するために設計されています。
 * 主にパスワードの安全な保存と検証に使用されます。
 * PHP 8 では、salt 引数を空文字列にすることで、自動的に強力な salt (ランダムな値) が生成され、
 * 利用可能な最も安全なアルゴリズム(例: Blowfish, SHA-512)が選択されます。
 *
 * 注意: 新しいアプリケーションでは、より簡潔で推奨されるパスワードハッシュ機能である
 * password_hash() および password_verify() の使用を検討してください。
 * crypt() は特定のレガシーシステムとの互換性や、より低レベルな制御が必要な場合に利用されます。
 */

/**
 * 指定された文字列を crypt() 関数でハッシュ化します。
 * PHP 8 では、salt 引数を空文字列にすることで、自動的に強力な salt とアルゴリズムが選択されます。
 *
 * @param string $inputString ハッシュ化する元の文字列。
 * @return string 生成されたハッシュ文字列。この文字列には salt とアルゴリズムの情報が含まれます。
 */
function createSecureHash(string $inputString): string
{
    // crypt() 関数は、元の文字列と salt を引数に取ります。
    // PHP 8 で salt を空文字列に設定すると、内部的に強力な salt が自動生成され、
    // 利用可能な最も安全なハッシュアルゴリズム(例: Blowfish)が選択されます。
    // 結果として生成されるハッシュは、salt とアルゴリズム情報を含んだ形式になります。
    $hashedString = crypt($inputString, ''); 
    return $hashedString;
}

/**
 * 元の文字列と保存されたハッシュを比較して検証します。
 *
 * crypt() 関数は、検証時に元の文字列と保存されたハッシュ(salt情報を含む)を引数として受け取ります。
 * 保存されたハッシュから salt とアルゴリズム情報を自動的に抽出し、
 * その情報に基づいて入力文字列を再度ハッシュ化し、結果を保存されたハッシュと比較します。
 *
 * @param string $inputString 検証する元の文字列。
 * @param string $storedHash 保存されているハッシュ文字列。
 * @return bool 文字列がハッシュと一致すれば true、そうでなければ false。
 */
function verifyHash(string $inputString, string $storedHash): bool
{
    // crypt() に元の文字列と保存されたハッシュを渡すことで、
    // crypt() は保存されたハッシュから salt を抽出し、同じアルゴリズムで入力文字列をハッシュ化し直します。
    $rehashedString = crypt($inputString, $storedHash);
    
    // hash_equals() は、タイミング攻撃を防ぐために、文字列を安全に比較します。
    return hash_equals($storedHash, $rehashedString);
}

// --- サンプルコードの実行 ---

$originalData = "mySensitiveData123";
echo "元のデータ: " . $originalData . PHP_EOL;

// データをハッシュ化
$generatedHash = createSecureHash($originalData);
echo "生成されたハッシュ: " . $generatedHash . PHP_EOL;

// 正しいデータでハッシュを検証
if (verifyHash($originalData, $generatedHash)) {
    echo "検証成功: 元のデータとハッシュが一致しました。" . PHP_EOL;
} else {
    echo "検証失敗: 元のデータとハッシュが一致しませんでした。" . PHP_EOL;
}

// 間違ったデータでハッシュを検証
$incorrectData = "wrongData456";
if (verifyHash($incorrectData, $generatedHash)) {
    echo "検証成功 (誤り): 間違ったデータとハッシュが一致しました。" . PHP_EOL;
} else {
    echo "検証失敗 (正しい): 間違ったデータとハッシュが一致しませんでした。" . PHP_EOL;
}

// crypt() で salt を自動生成する場合、同じ入力文字列でも毎回異なるハッシュが生成されます。
// これはセキュリティ機能であり、レインボーテーブル攻撃などから保護されます。
$anotherGeneratedHash = createSecureHash($originalData);
echo "再度生成されたハッシュ (異なるはず): " . $anotherGeneratedHash . PHP_EOL;

if ($generatedHash !== $anotherGeneratedHash) {
    echo "補足: 同じ入力文字列でも、crypt() は異なるハッシュを生成します (saltが毎回異なるため)。" . PHP_EOL;
}

?>

PHPのcrypt関数は、文字列を一方向のハッシュ値に変換するために使用される機能です。主にパスワードの安全な保存や検証に利用されます。この関数は、ハッシュ化したい元の文字列を$stringとして、そしてハッシュ化の強度を高めるための$saltを引数に取ります。PHP 8では$saltに空文字列を渡すと、システムが自動的に強力なsalt(ランダムな値)を生成し、利用可能な最も安全なハッシュアルゴリズム(例: Blowfish)が選択されます。

crypt関数は、元の文字列をハッシュ化して新しいハッシュ文字列を返します。この戻り値のハッシュ文字列には、使用されたsaltやアルゴリズムの情報が含まれています。ハッシュの検証時には、元の文字列と保存されているハッシュ文字列を再度crypt関数に渡すことで、関数が保存されたハッシュからsaltを抽出し、入力文字列を再ハッシュ化して比較します。これにより、元のデータと保存されたハッシュが一致するかを確認できます。

セキュリティ上の特性として、saltが毎回異なるため、同じ入力文字列であっても生成されるハッシュ値は通常異なります。これは、いわゆる「レインボーテーブル攻撃」といった一般的な攻撃からパスワードを保護するために重要です。また、ハッシュの比較には、タイミング攻撃を防ぐためにhash_equals関数を使用することが推奨されます。

なお、新しいアプリケーションでパスワードをハッシュ化する際には、より簡潔でセキュリティも強化されたpassword_hash()およびpassword_verify()関数を使用することが一般的に推奨されており、crypt()は特定のレガシーシステムとの互換性や、より低レベルな制御が必要な場合に利用されることがあります。

crypt()関数は主にパスワードなどの文字列を安全にハッシュ化し、検証するために利用されます。PHP 8では、salt引数を空文字列にすることで、自動的に強力なランダムなsaltと利用可能な最も安全なアルゴリズムが選択され、ハッシュが生成されます。同じ元の文字列であっても、生成されるハッシュはsaltが毎回異なるため、毎回異なるものになりますが、これはセキュリティを向上させるための機能です。ハッシュを検証する際は、元の文字列と保存されたハッシュをcrypt()関数に渡し、返された値をhash_equals()関数で安全に比較してください。しかし、新しいアプリケーションを開発する際には、より簡潔で推奨されるパスワードハッシュ関数であるpassword_hash()およびpassword_verify()の使用を検討してください。crypt()は特定のレガシーシステムとの互換性が必要な場合に有効です。

【PHP8.x】crypt関数の使い方 | いっしー@Webエンジニア