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

【PHP8.x】sodium_crypto_stream_keygen()関数の使い方

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

作成日: 更新日:

基本的な使い方

sodium_crypto_stream_keygen関数は、ストリーム暗号化に使用する、予測不可能で安全な新しい秘密鍵を生成する関数です。ストリーム暗号とは、データをバイト単位で連続的に暗号化・復号する仕組みのことで、大きなファイルやリアルタイムのデータストリームなど、大量のデータを効率的に処理する際に適しています。この関数は、暗号学的に強力な乱数生成器を用いて、セキュリティ上極めて重要な秘密鍵を生成します。

生成された秘密鍵は、sodium_crypto_stream_xorなどのPHPのSodium拡張が提供する他の関数と連携して使用されます。例えば、この鍵を使って元のデータを暗号化し、通信相手に安全に送信したり、受信した暗号化データを元の状態に戻したりすることができます。鍵はバイナリ文字列として返され、その長さはSODIUM_CRYPTO_STREAM_KEYBYTES定数によって保証されています。

この関数を利用することで、システムエンジニアを目指す方も、複雑な暗号学的な詳細に深く踏み込むことなく、PHPアプリケーションに堅牢な暗号化機能を組み込むことが可能です。安全な鍵の生成は、暗号システム全体のセキュリティ基盤となるため、この関数はデータの機密性を保護する上で非常に重要な役割を果たします。Sodium拡張は、最新の暗号技術に基づいた信頼性の高い機能を提供し、セキュアなアプリケーション開発を強力に支援します。

構文(syntax)

1<?php
2
3$key = sodium_crypto_stream_keygen();
4
5?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

string

この関数は、安全なストリーム暗号化に使用するための新しい鍵を生成し、その鍵をバイナリ文字列として返します。

サンプルコード

Libsodiumでストリーム暗号化キーを生成・利用する

1<?php
2
3// Libsodium extensionが有効になっているか確認
4if (!extension_loaded('sodium')) {
5    die('PHP extension "sodium" is not loaded. Please enable it in your php.ini.');
6}
7
8/**
9 * Libsodiumのsodium_crypto_stream_keygen関数を使用して、
10 * ストリーム暗号化のキーを生成し、その基本的な利用例を示します。
11 *
12 * このキーはストリーム暗号化 (例: sodium_crypto_stream) で使用されます。
13 * 共有秘密鍵認証付き暗号 (例: sodium_crypto_secretbox) には
14 * 別のキー生成関数 (sodium_crypto_secretbox_keygen) を使用します。
15 */
16function generateAndUseStreamEncryptionKey(): void
17{
18    // 1. ストリーム暗号化キーを生成
19    // sodium_crypto_stream_keygen は引数なしで、ストリーム暗号化用の安全なキーを返します。
20    // 戻り値はバイナリ文字列です。
21    $key = sodium_crypto_stream_keygen();
22
23    echo "生成されたストリーム暗号化キー (Hex): " . bin2hex($key) . "\n";
24    echo "キーの長さ: " . strlen($key) . " バイト (期待値: " . SODIUM_CRYPTO_STREAM_KEYBYTES . ")\n\n";
25
26    // 2. 暗号化に使用するメッセージとナンス (Nonce) を準備
27    $message = "これはPHP Libsodiumを使ったストリーム暗号化のテストメッセージです。";
28    // sodium_crypto_stream_nonce_gen はストリーム暗号化用の安全なナンスを生成します。
29    // 同じキーで複数のメッセージを暗号化する場合、異なるナンスを使用することが必須です。
30    $nonce = sodium_crypto_stream_nonce_gen();
31
32    echo "元のメッセージ: " . $message . "\n";
33    echo "生成されたナンス (Hex): " . bin2hex($nonce) . "\n";
34    echo "ナンスの長さ: " . strlen($nonce) . " バイト (期待値: " . SODIUM_CRYPTO_STREAM_NONCEBYTES . ")\n\n";
35
36    // 3. メッセージをストリーム暗号化
37    // sodium_crypto_stream は、指定されたキーとナンスでメッセージを暗号化します。
38    $cipherText = sodium_crypto_stream($message, $nonce, $key);
39
40    echo "暗号化されたメッセージ (Hex): " . bin2hex($cipherText) . "\n\n";
41
42    // 4. 暗号化されたメッセージを復号化
43    // sodium_crypto_stream を使用して、同じキーとナンスで元のメッセージに戻します。
44    $decryptedMessage = sodium_crypto_stream($cipherText, $nonce, $key);
45
46    echo "復号化されたメッセージ: " . $decryptedMessage . "\n\n";
47
48    // 5. 元のメッセージと復号化されたメッセージが一致するか確認
49    if ($message === $decryptedMessage) {
50        echo "✅ 検証成功: 元のメッセージと復号化されたメッセージは一致します。\n";
51    } else {
52        echo "❌ 検証失敗: メッセージが一致しません。\n";
53    }
54}
55
56// 関数の実行
57generateAndUseStreamEncryptionKey();
58
59?>

PHPのsodium_crypto_stream_keygen関数は、LibSodium拡張機能のストリーム暗号化秘密鍵生成関数です。引数なしで、sodium_crypto_streamでの暗号化・復号化に用いるバイナリ文字列のキーを返します。このキーは、sodium_crypto_secretboxのような認証付き暗号化キーとは目的が異なります。

サンプルコードでは、まずsodium_crypto_stream_keygenでキーを生成し、次にsodium_crypto_stream_nonce_genでナンス(使い捨ての乱数値)を用意します。同じキーで複数回暗号化する際は、ナンスを毎回異なるものにする必要があります。生成したキーとナンスでsodium_crypto_stream関数を使ってメッセージを暗号化し、続けて復号化します。最後に、元のメッセージと復号化されたメッセージの一致を確認します。

このサンプルコードを利用するには、PHPのLibsodium拡張機能が有効になっていることを確認してください。sodium_crypto_stream_keygen関数はストリーム暗号化専用のキーを生成します。キーワードにもあるsodium_crypto_secretboxのような認証付き暗号には、誤ってこのキーを使用せず、それぞれの目的に合ったキー生成関数(例: sodium_crypto_secretbox_keygen)を利用することが非常に重要です。また、同じキーで複数のメッセージを暗号化する際には、必ず異なるナンス(Nonce)を生成し使用してください。ナンスの再利用はセキュリティ上の重大な脆弱性につながります。生成されたキーは秘密情報として安全に管理し、決して公開しないようご注意ください。

sodium_crypto_stream_keygenで鍵生成と暗号化する

1<?php
2
3/**
4 * sodium_crypto_stream_keygen を使用した対称ストリーム暗号化の例。
5 *
6 * この関数は、システムエンジニアを目指す初心者のために、
7 * 対称鍵の生成、メッセージのストリーム暗号 (XSalsa20) による暗号化、
8 * および復号化の一連の流れを示します。
9 *
10 * @param string $message 暗号化する平文のメッセージ。
11 * @return void 元のメッセージ、暗号化されたメッセージ、復号化されたメッセージを出力します。
12 */
13function demonstrateSymmetricStreamEncryption(string $message): void
14{
15    // Sodium拡張機能が読み込まれているかを確認
16    if (!extension_loaded('sodium')) {
17        echo "エラー: Sodium拡張機能が読み込まれていません。" . PHP_EOL;
18        return;
19    }
20
21    // 1. sodium_crypto_stream_keygen を使用してストリーム暗号化用の秘密鍵を生成します。
22    // この鍵は対称鍵であり、メッセージの送受信者間で秘密に共有される必要があります。
23    $key = sodium_crypto_stream_keygen();
24    echo "生成されたストリーム鍵 (16進数): " . bin2hex($key) . PHP_EOL;
25    echo "鍵の長さ: " . strlen($key) . "バイト (期待値: " . SODIUM_CRYPTO_STREAM_KEYBYTES . ")" . PHP_EOL . PHP_EOL;
26
27    // 2. 各暗号化操作ごとに一意のNonce(ナンス:一度だけ使用される数値)を生成します。
28    // Nonceは秘密である必要はありませんが、同じ鍵で暗号化される各メッセージに対して異なる値である必要があります。
29    $nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);
30    echo "生成されたNonce (16進数): " . bin2hex($nonce) . PHP_EOL;
31    echo "Nonceの長さ: " . strlen($nonce) . "バイト (期待値: " . SODIUM_CRYPTO_STREAM_NONCEBYTES . ")" . PHP_EOL . PHP_EOL;
32
33    // 元のメッセージ
34    echo "元のメッセージ: " . $message . PHP_EOL . PHP_EOL;
35
36    // 3. ストリーム暗号(XSalsa20)を使用してメッセージを暗号化します。
37    // sodium_crypto_stream_xor は、提供された鍵とNonceを用いてメッセージを暗号化します。
38    $encryptedMessage = sodium_crypto_stream_xor($message, $nonce, $key);
39    echo "暗号化されたメッセージ (16進数): " . bin2hex($encryptedMessage) . PHP_EOL . PHP_EOL;
40
41    // 4. 同じ鍵とNonceを使用してメッセージを復号化します。
42    // ストリーム暗号(XSalsa20)では、同じ sodium_crypto_stream_xor 関数で暗号化と復号化の両方を行います。
43    $decryptedMessage = sodium_crypto_stream_xor($encryptedMessage, $nonce, $key);
44    echo "復号化されたメッセージ: " . $decryptedMessage . PHP_EOL . PHP_EOL;
45
46    // 5. 復号化の検証
47    if ($message === $decryptedMessage) {
48        echo "復号化成功: 元のメッセージと復号化されたメッセージが一致します。" . PHP_EOL;
49    } else {
50        echo "復号化失敗: 元のメッセージと復号化されたメッセージが一致しません。" . PHP_EOL;
51    }
52
53    // セキュリティのために、使用済みの秘密情報(鍵やNonce)をメモリからクリアします。
54    sodium_memzero($key);
55    sodium_memzero($nonce);
56    // メッセージ自体が機密情報を含む場合、これらもクリアすることが推奨されます。
57    sodium_memzero($message);
58    sodium_memzero($encryptedMessage);
59    sodium_memzero($decryptedMessage);
60}
61
62// 例として関数を実行
63demonstrateSymmetricStreamEncryption("システムエンジニア初心者さん、こんにちは!これは秘密のメッセージです。");
64
65?>

sodium_crypto_stream_keygenは、PHP 8で利用可能なSodium拡張機能に含まれる関数です。この関数は引数を取らず、対称ストリーム暗号化、特にXSalsa20アルゴリズムで使用される秘密鍵を生成します。生成された鍵は文字列(string)として返され、メッセージの暗号化と復号化の両方に使用されるため、通信の送受信者間で秘密に共有される必要があります。

提示されたサンプルコードは、このsodium_crypto_stream_keygen関数で生成された秘密鍵を用いた対称ストリーム暗号化の具体的な手順をシステムエンジニアを目指す初心者向けに解説しています。まず、sodium_crypto_stream_keygenにより安全な対称鍵が生成されます。次に、暗号化ごとに一意のNonce(ナンス:一度だけ使用される数値)が生成され、この鍵とNonceを使ってsodium_crypto_stream_xor関数で平文メッセージが暗号化されます。復号化は、同じsodium_crypto_stream_xor関数に暗号化されたメッセージと、暗号化時と同じ鍵およびNonceを渡すことで実行されます。最終的に、復号化されたメッセージが元のメッセージと一致することを確認し、セキュリティ確保のためにsodium_memzero関数で秘密情報がメモリから安全にクリアされる一連の流れを示しています。

Sodium拡張機能がPHPにインストールされ、有効になっていることを必ず確認してください。生成された鍵は極めて重要であり、送受信者間で厳重に秘密に共有し、決して漏洩させないでください。各暗号化処理では、Nonce(ナンス)を必ず一意に生成し、使い回さないようにしてください。Nonceが重複するとセキュリティが危険に晒されます。暗号化と復号化には、全く同じ鍵とNonceの組み合わせを使用する必要があります。最後に、セキュリティを確保するため、使用済みの鍵やメッセージなどの機密情報は、sodium_memzero関数を用いて速やかにメモリから消去することを忘れないでください。

関連コンテンツ

関連プログラミング言語