【PHP8.x】sodium_crypto_generichash_keygen()関数の使い方
sodium_crypto_generichash_keygen関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
sodium_crypto_generichash_keygen関数は、PHPのlibsodium拡張機能が提供する汎用ハッシュ関数sodium_crypto_generichashで使用するための、暗号学的に安全なハッシュキーを生成する関数です。
この関数は、メッセージ認証コード(MAC: Message Authentication Code)を生成する際に利用される秘密鍵を生成することを主な目的としています。MACは、データの完全性(データが途中で改ざんされていないこと)と、データの真正性(データが信頼できる送信者によって作成されたこと)を検証するために用いられる暗号技術です。
sodium_crypto_generichash_keygen関数が生成するキーは、暗号学的に強力な擬似乱数生成器によって作成されたバイナリ文字列であり、外部に漏洩しないよう厳重に管理される必要があります。この関数は引数を取ることはなく、呼び出すたびに新しい秘密のキーが返されます。
生成されたハッシュキーは、sodium_crypto_generichash関数に渡すことで、特定のメッセージに対するセキュアなハッシュ値(MAC)を計算するために利用されます。これにより、受信者は同じキーを使って計算されたハッシュ値と比較することで、メッセージの改ざんを検知したり、送信元を認証したりすることが可能になります。このキーの秘匿性は、データのセキュリティを確保する上で非常に重要な要素となります。システムエンジニアを目指す初心者の方々にとって、安全なデータ通信や保存を実装するための基礎として理解されるでしょう。
構文(syntax)
1<?php 2 3$key = sodium_crypto_generichash_keygen(); 4 5?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string
安全なキーを生成し、それをバイナリ文字列として返します。
サンプルコード
PHP Sodium: ハッシュキー生成と公開鍵暗号
1<?php 2 3/** 4 * PHPのSodium拡張における、ジェネリックハッシュキー生成と公開鍵暗号の使用例を示します。 5 * システムエンジニアを目指す初心者向けに、各機能の基本的な目的と使い方を解説します。 6 */ 7function demonstrateSodiumCryptoFeatures(): void 8{ 9 // --- sodium_crypto_generichash_keygen の使用例 (汎用ハッシュキー生成とハッシュ) --- 10 echo "--- 汎用ハッシュキーの生成とデータのハッシュ化 ---\n"; 11 12 // sodium_crypto_generichash_keygen は、汎用ハッシュ関数 (sodium_crypto_generichash) で 13 // 使用するためのランダムなキーを生成します。引数は不要です。 14 // このキーは、データの完全性や真正性を検証する際に利用できます。 15 $genericHashKey = sodium_crypto_generichash_keygen(); 16 echo "生成された汎用ハッシュキー (バイナリを16進数で表示): " . bin2hex($genericHashKey) . "\n"; 17 18 // ハッシュする対象のデータ 19 $dataToHash = "このデータはハッシュによってその内容の改ざんを検知できます。"; 20 echo "ハッシュするデータ: '" . $dataToHash . "'\n"; 21 22 // 生成したキーとデータを使用してハッシュ値を計算します。 23 // 同じデータとキーからは常に同じハッシュ値が生成されますが、 24 // データやキーが少しでも異なると、全く異なるハッシュ値が生成されます。 25 $hashedData = sodium_crypto_generichash($dataToHash, $genericHashKey); 26 echo "生成されたハッシュ値: " . bin2hex($hashedData) . "\n\n"; 27 28 29 // --- sodium_crypto_box の使用例 (公開鍵暗号によるメッセージの安全な交換) --- 30 echo "--- 公開鍵暗号によるメッセージの暗号化と復号化 ---\n"; 31 32 // sodium_crypto_box は、公開鍵暗号システムを使用して、メッセージの機密性と認証を提供します。 33 // これは、メッセージを安全に交換するために使用されます。 34 35 // 1. 送信者(Alice)と受信者(Bob)の鍵ペアをそれぞれ生成します。 36 // 鍵ペアは秘密鍵と公開鍵のセットです。秘密鍵は絶対に秘密に保ち、公開鍵は共有可能です。 37 $aliceKeypair = sodium_crypto_box_keypair(); 38 $alicePublicKey = sodium_crypto_box_publickey($aliceKeypair); 39 $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeypair); 40 41 $bobKeypair = sodium_crypto_box_keypair(); 42 $bobPublicKey = sodium_crypto_box_publickey($bobKeypair); 43 $bobSecretKey = sodium_crypto_box_secretkey($bobKeypair); 44 45 echo "Aliceの公開鍵: " . bin2hex($alicePublicKey) . "\n"; 46 echo "Bobの公開鍵: " . bin2hex($bobPublicKey) . "\n\n"; 47 48 // 2. AliceがBobに送りたい秘密のメッセージ 49 $secretMessage = "Hello Bob! This is a secret message from Alice."; 50 echo "元の秘密メッセージ: '" . $secretMessage . "'\n"; 51 52 // 3. ノンス (Nonce: Number used once) を生成します。 53 // ノンスは使い捨てのランダムな値で、同じメッセージと鍵ペアでも異なる暗号文を生成し、 54 // リプレイ攻撃(過去の通信を再送することで不正アクセスを試みる攻撃)を防ぐために必須です。 55 // ノンスは暗号化・復号化の両方に使用され、秘密にする必要はありませんが、絶対に使い回してはいけません。 56 $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES); 57 echo "生成されたノンス: " . bin2hex($nonce) . "\n"; 58 59 // 4. Aliceがメッセージを暗号化します。 60 // Aliceは「Bobの公開鍵」と「自身の秘密鍵」を使ってメッセージを暗号化します。 61 // これにより、Bobだけがメッセージを復号でき、メッセージがAliceから来たことも保証されます。 62 $encryptedMessage = sodium_crypto_box($secretMessage, $nonce, $bobPublicKey, $aliceSecretKey); 63 echo "暗号化されたメッセージ: " . bin2hex($encryptedMessage) . "\n"; 64 65 // 5. Bobがメッセージを復号化します。 66 // Bobは「Aliceの公開鍵」と「自身の秘密鍵」、そして「Aliceから受け取ったノンス」を使ってメッセージを復号します。 67 // 復号に成功すれば、メッセージがAliceから送られ、途中で改ざんされていないことが確認できます。 68 $decryptedMessage = sodium_crypto_box_open($encryptedMessage, $nonce, $alicePublicKey, $bobSecretKey); 69 70 if ($decryptedMessage !== false) { 71 echo "復号化されたメッセージ: '" . $decryptedMessage . "'\n"; 72 if ($decryptedMessage === $secretMessage) { 73 echo "メッセージは正常に復号化され、元の内容と一致しました。\n"; 74 } else { 75 echo "メッセージの復号化に成功しましたが、内容が元のメッセージと一致しませんでした (改ざんの可能性)。\n"; 76 } 77 } else { 78 echo "メッセージの復号化に失敗しました。鍵、ノンス、またはメッセージが間違っている可能性があります。\n"; 79 } 80} 81 82// 関数を実行してデモンストレーションを開始します。 83demonstrateSodiumCryptoFeatures(); 84 85?>
PHPのSodium拡張は、暗号技術を安全かつ簡単に利用するための機能を提供します。このサンプルコードでは、セキュリティの基礎となる二つの重要な概念、データのハッシュ化と公開鍵暗号について説明します。
sodium_crypto_generichash_keygen関数は、汎用ハッシュ関数で使用するためのランダムなキーを生成します。この関数は引数なしで呼び出され、ランダムなバイト列を文字列として返します。生成されたキーは、sodium_crypto_generichashと組み合わせてデータをハッシュ化する際に利用され、データの完全性や真正性を検証するのに役立ちます。同じデータとキーからは常に同じハッシュ値が得られますが、データやキーが少しでも異なると、全く異なるハッシュ値が生成されるため、改ざんの検知に有効です。
次に、sodium_crypto_box関数は、公開鍵暗号システムに基づいてメッセージの暗号化と復号化を行います。これは、メッセージの内容を秘密にし、かつ送信者が誰であるかを保証するために使われます。具体的には、送信者と受信者がそれぞれ持つ鍵ペア(公開鍵と秘密鍵のセット)と、一回だけ使用されるランダムな値であるノンスを用いてメッセージを暗号化・復号化します。送信者は受信者の公開鍵と自身の秘密鍵でメッセージを暗号化し、受信者は自身の秘密鍵と送信者の公開鍵、そして受け取ったノンスを使ってメッセージを復号します。これにより、メッセージが安全に交換され、途中で改ざんされていないことが確認できます。
sodium_crypto_generichash_keygenで生成されるハッシュキーは、データの完全性や真正性を検証する際に利用されます。このキーは秘密に保ち、外部に漏洩しないよう厳重に管理してください。
公開鍵暗号のsodium_crypto_boxでは、秘密鍵は絶対に秘密に保ち、公開鍵のみを安全に共有してください。特に重要なのはノンス(Nonce)で、これはメッセージごとに必ず使い捨ててください。ノンスを再利用すると、リプレイ攻撃など深刻なセキュリティ上の脆弱性となります。ノンスは毎回新しく生成し、暗号文と一緒に相手に渡す必要があります。
これらの関数が返す値はバイナリデータのため、画面表示やデータベースへの保存時にはbin2hexやbase64_encodeなどで適切にエンコード・デコードしてください。また、復号化関数であるsodium_crypto_box_openは、復号に失敗した場合にfalseを返すため、必ず戻り値を確認し、エラー処理を実装するようにしてください。
Libsodium汎用ハッシュキー生成と利用
1<?php 2 3/** 4 * Libsodiumの汎用ハッシュキー生成と利用のサンプルコード。 5 * システムエンジニアを目指す初心者向けに、正確で簡潔なコードを提供します。 6 * PHP 8 環境で Libsodium 拡張機能が有効になっている必要があります。 7 */ 8function demonstrateGenericHashKeyGeneration(): void 9{ 10 // Libsodium拡張機能が利用可能か確認 11 // PHP 8では、`php.ini`で `extension=sodium` を有効にするか、インストールを確認してください。 12 if (!extension_loaded('sodium')) { 13 echo "エラー: Libsodium拡張機能が有効になっていません。\n"; 14 echo "このサンプルコードを実行するには、LiblsodiumのPHP拡張機能が必要です。\n"; 15 return; 16 } 17 18 echo "=== Libsodium 汎用ハッシュキー生成と利用のサンプル ===\n\n"; 19 20 // 1. `sodium_crypto_generichash_keygen` を使って、汎用ハッシュ用のキーを生成します。 21 // この関数は引数なしで、安全なランダムな固定長キー(通常 32 バイト)を生成し、 22 // バイナリ形式の `string` 型で返します。 23 $hashKey = sodium_crypto_generichash_keygen(); 24 echo "生成された汎用ハッシュキー (バイナリを16進数で表示): " . bin2hex($hashKey) . "\n"; 25 echo "キーの長さ: " . strlen($hashKey) . " バイト\n\n"; // `generichash_keygen` は常に 32 バイトのキーを生成 26 27 // 2. 生成されたハッシュキーを使用して、データのハッシュを計算します。 28 // `sodium_crypto_generichash` は、データとオプションでキーを受け取り、ハッシュを生成します。 29 // キーを使用することで、メッセージ認証コード (MAC) のように利用でき、データの完全性と認証を保証できます。 30 $message = "これはハッシュ化する秘密のメッセージです。"; 31 echo "元のメッセージ: " . $message . "\n"; 32 33 // `sodium_crypto_generichash` のデフォルトハッシュ長は `SODIUM_CRYPTO_GENERICHASH_BYTES_MAX` (64バイト) です。 34 // オプションで第三引数にハッシュ長を指定することも可能です。 35 $genericHash = sodium_crypto_generichash($message, $hashKey); 36 echo "メッセージの汎用ハッシュ (キー付き): " . bin2hex($genericHash) . "\n\n"; 37 38 // 3. キーがない場合のハッシュ計算 39 // キーを渡さない場合でもハッシュ計算は可能ですが、 40 // メッセージ認証にはキー付きハッシュ(MAC)の使用が強く推奨されます。 41 $genericHashNoKey = sodium_crypto_generichash($message); 42 echo "メッセージの汎用ハッシュ (キーなし): " . bin2hex($genericHashNoKey) . "\n\n"; 43 44 // 補足: キーワード `sodium_crypto_secretbox` について 45 // `sodium_crypto_secretbox` は、メッセージの認証付き対称暗号化を行うための関数です。 46 // ここで生成された `hashKey` は、メッセージのハッシュ計算に特化しており、 47 // `sodium_crypto_secretbox` で暗号化・復号化するためのキーとしては使用できません。 48 // `sodium_crypto_secretbox` には、専用の `secretbox` キー 49 // (`sodium_crypto_secretbox_keygen` で生成) と `nonce` (ナンバー・ワンス) が必要となります。 50 // これらのセキュリティ機能は目的が異なるため、適切に使い分けることが重要です。 51} 52 53// スクリプトの実行 54demonstrateGenericHashKeyGeneration(); 55 56?>
sodium_crypto_generichash_keygenは、PHP 8で利用可能なLibsodium拡張機能が提供する関数の一つです。この関数は引数を取らずに呼び出すことができ、汎用ハッシュの計算に利用される安全なランダムキーを、バイナリ形式の文字列として生成して返します。生成されるキーは通常32バイトの固定長です。
この生成されたキーは、sodium_crypto_generichash関数と組み合わせて使用することで、メッセージ認証コード(MAC)を生成するために非常に重要です。MACを利用することで、メッセージの完全性(内容が改ざんされていないこと)と、認証(メッセージが信頼できる送信元から送られたこと)を同時に検証できるようになります。キーなしでもハッシュ計算は可能ですが、セキュリティを確保し、メッセージ認証を行いたい場合には、この関数で生成したキーの利用が強く推奨されます。
また、キーワードとして示されたsodium_crypto_secretboxは、メッセージの暗号化と認証付きの対称暗号化を行うための関数であり、sodium_crypto_generichash_keygenで生成されるハッシュキーとは異なる目的で使用されます。sodium_crypto_secretboxには専用のキーが必要となるため、それぞれのセキュリティ機能の目的に合わせて適切なキーと関数を使い分けることが重要です。
sodium_crypto_generichash_keygenは、メッセージの完全性と認証を目的とした汎用ハッシュキーを生成します。このキーは常に秘密に管理し、安全に取り扱う必要があります。生成されるキーは固定長のバイナリ文字列です。このキーは汎用ハッシュ関数(MAC)専用であり、サンプルコードで言及されているsodium_crypto_secretboxのようなメッセージの暗号化に使うキーとは役割が異なります。暗号化にはsodium_crypto_secretbox_keygenなどで生成される専用のキーを使用してください。サンプルコードを実行するには、PHP環境でLibsodium拡張機能が有効になっていることが必須です。用途に合わせたキーの使い分けが重要です。