Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数の使い方

SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数は、PHPのlibsodium拡張機能において、パスワードハッシュ処理に利用するアルゴリズムの一つであるArgon2i バージョン1.3を表す定数です。この定数は、パスワードや機密性の高い情報を安全に保存するために使用されるsodium_crypto_pwhashなどの関数で、具体的にどのハッシュアルゴリズムを用いるかを指定する際に利用されます。

Argon2iは、ブルートフォース攻撃や辞書攻撃といったパスワード推測攻撃に対して非常に高い耐性を持つように設計された、現代的で堅牢なパスワードハッシュアルゴリズムです。その強度は、意図的に多くのメモリとCPU時間を消費させることで、攻撃者が大量のパスワード候補を試行するコストを大幅に増加させる点にあります。バージョン1.3は、Argon2iアルゴリズムの特定のバージョンを示し、その時点での推奨されるセキュリティ特性を提供します。

もしデータベースからパスワードハッシュが漏洩したとしても、この強力なArgon2iアルゴリズムが適用されていれば、攻撃者が元のパスワードを特定するまでには多大な時間と計算リソースが必要となり、不正アクセスへの時間的猶予や阻止の可能性を高めます。システムエンジニアを目指す方にとって、ユーザーのパスワードを安全に管理することはアプリケーションの信頼性を保つ上で極めて重要です。このSODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数を活用することで、PHP 8環境におけるパスワードセキュリティを効果的に強化できます。

構文(syntax)

1<?php
2echo SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13;

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

Argon2iアルゴリズムのバージョン13を示す整数定数です。

サンプルコード

PHP Sodiumでパスワードハッシュ化する

1<?php
2
3/**
4 * PHP Sodium拡張を使ったパスワードハッシュのデモンストレーション。
5 *
6 * SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数を使用して、
7 * Argon2iアルゴリズムでパスワードをハッシュ化し、検証する例です。
8 *
9 * 「php sodium と は」: PHPのSodium拡張は、暗号化操作を安全に行うためのライブラリです。
10 * パスワードハッシュはその主要な機能の一つで、ユーザー認証などで安全なパスワード管理を実現します。
11 */
12function demonstrateSodiumPwhash(): void
13{
14    // ① ハッシュ化する元のパスワード
15    $password = 'my_secure_password_123';
16    echo "元のパスワード: " . $password . "\n\n";
17
18    // ② パスワードハッシュのアルゴリズムと設定
19    // SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 は、Argon2iアルゴリズムのバージョン13を指定します。
20    // これはPHP Sodiumが提供する推奨される強力なパスワードハッシュアルゴリズムの一つです。
21    $algorithm = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13;
22
23    // ソルト(Salt)は、ハッシュのセキュリティを高めるためのランダムなデータです。
24    // sodium_randombytes_buf は暗号学的に安全な乱数を生成します。
25    $salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
26
27    // 操作回数 (opslimit) とメモリ制限 (memlimit) は、ハッシュ計算のコストを制御します。
28    // これらの値が高いほど、ハッシュ化と検証に時間がかかり、ブルートフォース攻撃が困難になります。
29    // INTERACTIVEは、ログインのような対話型アプリケーションに適した推奨値です。
30    $opslimit = SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE;
31    $memlimit = SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE;
32
33    // 生成するハッシュのバイト数
34    $hashLength = SODIUM_CRYPTO_PWHASH_BYTES;
35
36    // ③ パスワードのハッシュ化
37    // sodium_crypto_pwhash 関数を使ってパスワードをハッシュ化します。
38    // この関数はバイナリデータ(生のバイト列)を返します。
39    $hashedPassword = sodium_crypto_pwhash(
40        $hashLength,
41        $password,
42        $salt,
43        $opslimit,
44        $memlimit,
45        $algorithm
46    );
47
48    // ハッシュ値とソルトはバイナリデータなので、データベースなどに保存するために
49    // Base64エンコードして文字列形式に変換するのが一般的です。
50    $encodedHashedPassword = base64_encode($hashedPassword);
51    $encodedSalt = base64_encode($salt);
52
53    echo "--- ハッシュ化された情報 (通常はDBに保存) ---\n";
54    echo "ハッシュ (Base64エンコード): " . $encodedHashedPassword . "\n";
55    echo "ソルト (Base64エンコード):   " . $encodedSalt . "\n";
56    echo "アルゴリズム:              " . $algorithm . " (SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13)\n";
57    echo "操作回数制限:              " . $opslimit . "\n";
58    echo "メモリ制限:                " . $memlimit . "バイト\n\n";
59
60    // ④ パスワードの検証
61    // ユーザーがログイン時にパスワードを入力した際、保存されたハッシュと比較して一致するか確認します。
62    // 保存されたソルト、opslimit、memlimit、algorithmを使って、入力パスワードを再度ハッシュ化します。
63    echo "--- パスワードの検証 (ログイン時など) ---\n";
64
65    // データベースから取得したと仮定する情報
66    $dbHashedPassword = base64_decode($encodedHashedPassword); // 保存されたハッシュをデコード
67    $dbSalt = base64_decode($encodedSalt);                     // 保存されたソルトをデコード
68    $dbOpslimit = $opslimit;                                   // 保存されたopslimit
69    $dbMemlimit = $memlimit;                                   // 保存されたmemlimit
70    $dbAlgorithm = $algorithm;                                 // 保存されたアルゴリズム
71
72    // 検証するパスワード (ユーザーがログインフォームに入力したと仮定)
73    $inputPassword = 'my_secure_password_123';
74    echo "入力されたパスワード: " . $inputPassword . "\n";
75
76    $isValid = (
77        sodium_crypto_pwhash(
78            $hashLength,
79            $inputPassword, // ユーザーが入力したパスワード
80            $dbSalt,        // DBから取得したソルト
81            $dbOpslimit,
82            $dbMemlimit,
83            $dbAlgorithm
84        ) === $dbHashedPassword
85    );
86
87    if ($isValid) {
88        echo "✅ パスワードは正しく検証されました。\n";
89    } else {
90        echo "❌ パスワードが一致しません。\n";
91    }
92
93    // 間違ったパスワードでの検証例
94    echo "\n--- 間違ったパスワードでの検証 --- \n";
95    $wrongPassword = 'wrong_password_123';
96    echo "入力されたパスワード: " . $wrongPassword . "\n";
97
98    $isWrongValid = (
99        sodium_crypto_pwhash(
100            $hashLength,
101            $wrongPassword,
102            $dbSalt,
103            $dbOpslimit,
104            $dbMemlimit,
105            $dbAlgorithm
106        ) === $dbHashedPassword
107    );
108
109    if ($isWrongValid) {
110        echo "❌ 誤ってパスワードが検証されました (このメッセージは表示されないはずです)。\n";
111    } else {
112        echo "✅ 間違ったパスワードは正しく拒否されました。\n";
113    }
114}
115
116// 関数を実行してデモンストレーションを開始
117demonstrateSodiumPwhash();

PHPのSodium拡張は、暗号化処理を安全に行うためのライブラリです。特に、ユーザーのパスワードを安全に管理する「パスワードハッシュ」機能は、その主要な用途の一つです。

SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13は、PHP Sodium拡張でパスワードをハッシュ化する際に利用する定数です。これは、現代において非常に強力で推奨される「Argon2i」アルゴリズムのバージョン13を指定します。この定数自体は引数を取らず、内部的にアルゴリズムの種類を識別するための整数値を返します。

サンプルコードでは、この定数をsodium_crypto_pwhash関数に渡してパスワードをハッシュ化しています。ハッシュ化では、元のパスワードに加え、セキュリティを高めるためのランダムなデータであるソルト、計算コストを調整する操作回数(opslimit)やメモリ制限(memlimit)といったパラメータも使用します。これらのパラメータが高いほど、ハッシュ化にかかる時間とリソースが増え、ブルートフォース攻撃に対する耐性が向上します。

生成されたハッシュ値は、元のパスワードを直接保存する代わりにデータベースなどに保存されます。これにより、万が一データベースが漏洩しても元のパスワードが特定されるリスクを大幅に低減できます。ユーザーがログインする際は、入力されたパスワードを保存されたソルトや他のパラメータ、そしてSODIUM_CRYPTO_PWHASH_ALG_ARGON2I13で指定されたアルゴリズムを使って再度ハッシュ化し、保存されているハッシュ値と一致するかを比較して認証を行います。これにより、安全なユーザー認証システムを構築することが可能になります。

SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13は強力なハッシュアルゴリズムですが、パスワードハッシュの安全性は、opslimit(操作回数制限)やmemlimit(メモリ制限)、ランダムなsalt(ソルト)と組み合わせて初めて高まります。これらの設定値は、本番環境のサーバーリソースを考慮して調整することが重要です。ハッシュ値とソルトはバイナリデータなので、データベースなどに保存する際はBase64エンコードなどで文字列に変換し、使用する際は必ずデコードして元に戻す必要があります。パスワードの検証では、ユーザーの入力パスワードを保存時と全く同じソルト、opslimitmemlimit、アルゴリズムでハッシュ化し、保存されているハッシュ値と厳密に比較(===)することが必須です。PHPのSodium拡張は、このような暗号学的に安全なパスワード処理を提供する重要なライブラリです。

nonceサイズをsodium_crypto_aead_aes256gcm_npubbytes()で取得する

1<?php
2
3/**
4 * Demonstrates authenticated encryption and decryption using AES256-GCM.
5 *
6 * This function showcases how to use libsodium's AES256-GCM authenticated encryption
7 * functionality in PHP. It specifically highlights the use of
8 * `sodium_crypto_aead_aes256gcm_npubbytes()` to determine the correct size
9 * for the nonce (number used once), which is crucial for secure operations.
10 *
11 * For a beginner System Engineer, understanding how to securely encrypt and decrypt
12 * data is fundamental. This example uses a strong, modern cryptographic primitive.
13 */
14function demonstrateAeadGcmEncryption(): void
15{
16    // Ensure the Sodium extension is loaded. If not, this script cannot proceed.
17    if (!extension_loaded('sodium')) {
18        echo "Error: The 'sodium' extension is not loaded. Please enable it in your PHP configuration.\n";
19        return;
20    }
21
22    // 1. Generate a secure random key for AES256-GCM.
23    // SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES provides the required key length (32 bytes for AES-256).
24    $key = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES);
25    echo "--- Encryption Key ---\n";
26    echo "Key (hex): " . bin2hex($key) . "\n\n";
27
28    // The sensitive message we want to encrypt.
29    $originalMessage = "Hello, System Engineer beginner! This is a confidential message that needs protection.";
30    echo "--- Original Message ---\n";
31    echo "Message: " . $originalMessage . "\n\n";
32
33    // 2. Get the required nonce (public number) size for AES256-GCM.
34    // `sodium_crypto_aead_aes256gcm_npubbytes()` returns the exact number of bytes
35    // needed for a nonce, ensuring compatibility and security.
36    $nonceSize = sodium_crypto_aead_aes256gcm_npubbytes();
37    echo "--- Nonce Information ---\n";
38    echo "Required Nonce Bytes (from sodium_crypto_aead_aes256gcm_npubbytes()): " . $nonceSize . " bytes\n";
39
40    // 3. Generate a secure random nonce of the required size.
41    // It is CRITICAL that the nonce is unique for every encryption operation with the same key.
42    // Reusing a nonce with the same key compromises security.
43    $nonce = random_bytes($nonceSize);
44    echo "Generated Nonce (hex): " . bin2hex($nonce) . "\n\n";
45
46    // 4. Optional: Define Associated Additional Data (AAD).
47    // AAD is data that is authenticated but not encrypted. It can be used to bind
48    // non-confidential information (like a message ID or version) to the ciphertext.
49    // It must be provided during both encryption and decryption.
50    $associatedData = "message_metadata_v1.0";
51    echo "--- Associated Additional Data (AAD) ---\n";
52    echo "AAD: " . $associatedData . "\n\n";
53
54    // 5. Encrypt the message using AES256-GCM.
55    // The output `$ciphertext` includes the encrypted message and an authentication tag.
56    $ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
57        $originalMessage,
58        $associatedData,
59        $nonce,
60        $key
61    );
62    echo "--- Encrypted Data ---\n";
63    echo "Ciphertext (hex): " . bin2hex($ciphertext) . "\n\n";
64
65    // --- Decryption Phase ---
66    echo "--- Decryption Attempt ---\n";
67
68    // 6. Decrypt the message.
69    // All parameters (ciphertext, AAD, nonce, key) must be identical to those used
70    // during encryption. If any byte is changed, decryption will fail due to
71    // authentication tag mismatch, indicating tampering.
72    try {
73        $decryptedMessage = sodium_crypto_aead_aes256gcm_decrypt(
74            $ciphertext,
75            $associatedData,
76            $nonce,
77            $key
78        );
79
80        echo "Decrypted Message: " . $decryptedMessage . "\n\n";
81
82        // 7. Verify that the decrypted message matches the original.
83        if ($originalMessage === $decryptedMessage) {
84            echo "Verification: Encryption and Decryption successful and data integrity confirmed!\n";
85        } else {
86            echo "Verification: Decryption failed or message mismatch! Data tampering suspected or parameters incorrect.\n";
87        }
88    } catch (SodiumException $e) {
89        // Handle cases where decryption fails (e.g., tampering detected).
90        echo "Decryption failed: " . $e->getMessage() . "\n";
91        echo "This typically indicates that the ciphertext, nonce, key, or AAD was incorrect or tampered with.\n";
92    }
93}
94
95// Execute the demonstration function.
96demonstrateAeadGcmEncryption();

このサンプルコードは、PHPのsodium拡張機能を用いて、AES256-GCMアルゴリズムによる認証付き暗号化と復号を行う方法を示しています。データの機密性(暗号化)と完全性(改ざん検知)を同時に保護する、現代的で堅牢な手法をシステムエンジニアの初心者の方にも理解しやすいように解説しています。

コードの中心となるsodium_crypto_aead_aes256gcm_npubbytes()関数は、認証付き暗号化に必要なNonce(使い捨ての数値)の正確なバイト数を取得するために使用されます。この関数は引数を持たず、Nonceに必要なバイト数を整数(int)として返します。安全な暗号化操作のためには、この関数が示す正確なサイズでNonceを生成し、同じ鍵で暗号化する際には毎回異なるNonceを使用することが極めて重要です。

サンプルでは、まずセキュアな鍵と、sodium_crypto_aead_aes256gcm_npubbytes()で取得したサイズの一意なNonceを生成します。次に、保護したいメッセージとオプションの付加認証データ(AAD)を用いてメッセージを暗号化します。生成される暗号文には、暗号化されたメッセージ本体と改ざん検出のための認証タグが含まれます。復号時には、暗号文、同じAAD、Nonce、そして鍵をすべて正確に提供することで、元のメッセージが復元されます。もしこれらの情報が一つでも異なると、改ざんを検知して復号が失敗し、データが不正に変更されていないことを確認できます。

なお、参照情報にあったSODIUM_CRYPTO_PWHASH_ALG_ARGON2I13定数は、このコードでは直接使用されていませんが、一般的にはsodium拡張機能でパスワードを安全にハッシュ化する際に、Argon2iのバージョン1.3アルゴリズムを指定するために利用される整数型の定数です。

PHPのsodium拡張機能を利用する際は、まずPHP設定で拡張機能が有効になっていることを確認してください。暗号化に使う鍵とノンスは、random_bytes()関数などで安全な乱数を用いて生成することが必須です。特にノンスは、同じ鍵で暗号化する際は常に異なる値を使用しなければなりません。ノンスの再利用は重大なセキュリティリスクを招きます。また、関連追加データ(AAD)は暗号化時と復号時で完全に一致させる必要があります。復号時にSodiumExceptionが発生する場合、データが改ざんされたか、提供された鍵、ノンス、AADのいずれかに誤りがある可能性が高いと判断できます。これらの点を守ることで、安全な暗号化通信を実現できます。

関連コンテンツ

関連IT用語

関連プログラミング言語