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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_stream_xchacha20_keygen関数は、XChaCha20ストリーム暗号方式で使用する秘密鍵を安全に生成する関数です。この関数は、データの暗号化や復号化を行う際に必要となる、予測不可能なランダムな鍵を作成するために利用されます。

生成される鍵は、XChaCha20アルゴリズムの仕様に基づいた固定長(32バイト)のバイナリデータです。これは、データを安全に保護するための「秘密のパスワード」のような役割を果たします。この関数は、PHPの標準拡張機能であるlibsodiumライブラリの一部として提供されており、堅牢な暗号化機能を手軽に利用できる点が特徴です。

暗号学的に安全な乱数生成器を用いて鍵を生成するため、悪意のある第三者によって鍵が推測されるリスクを低減し、高いセキュリティを確保します。例えば、機密性の高いデータをファイルに保存する前や、ネットワーク経由で安全に送受信する際に、この関数で生成した鍵を使ってデータを暗号化し、データの機密性を保つことができます。生成された鍵は非常に重要であるため、厳重に管理し、決して外部に漏洩しないように細心の注意を払う必要があります。

構文(syntax)

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

引数(parameters)

引数なし

引数はありません

戻り値(return)

string

X25519 暗号化用のランダムな 32 バイトのキーをバイナリ文字列として返します。

サンプルコード

PHP Sodium: XChaCha20 鍵生成と暗号化

1<?php
2
3declare(strict_types=1);
4
5/**
6 * XChaCha20 ストリーム暗号用の鍵を生成し、データの暗号化と復号を行うサンプル関数。
7 *
8 * この関数は `sodium_crypto_stream_xchacha20_keygen()` を使用して、
9 * 対称鍵暗号化に必要な秘密鍵を生成します。
10 * 生成された鍵とノンスを用いてデータを暗号化し、その後復号する一連の流れを示します。
11 * これは、システムエンジニアがデータ保護のために使用できる基本的な暗号化の一例です。
12 */
13function runXChaCha20EncryptionExample(): void
14{
15    // Sodium 拡張がロードされているかを確認
16    if (!extension_loaded('sodium')) {
17        echo "エラー: Sodium 拡張がロードされていません。PHPの設定を確認してください。\n";
18        return;
19    }
20
21    echo "--- XChaCha20 ストリーム暗号の鍵生成と使用例 ---\n\n";
22
23    // 1. XChaCha20 ストリーム暗号用の秘密鍵を生成
24    // `sodium_crypto_stream_xchacha20_keygen()` は、引数なしで安全な32バイトの秘密鍵を生成します。
25    // この鍵は、データの暗号化と復号の両方に使用される対称鍵です。
26    $key = sodium_crypto_stream_xchacha20_keygen();
27    echo "秘密鍵を生成しました (長さ: " . strlen($key) . " バイト)\n";
28    // 通常、秘密鍵は表示しません。ここでは長さの確認のみ行っています。
29    echo "秘密鍵の生成完了。\n\n";
30
31    // 2. 暗号化したい元の平文データ
32    $plainText = "秘密のメッセージをSodiumで安全に転送しましょう!";
33    echo "元の平文: \"" . $plainText . "\"\n";
34    echo "元の平文の長さ: " . strlen($plainText) . " バイト\n\n";
35
36    // 3. XChaCha20 ストリーム暗号用のノンスを生成
37    // ノンス(Number Used Once)は、暗号化ごとに必ず異なる値である必要があります。
38    // `random_bytes()` を使用して、`SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES` で定義された
39    // 適切な長さ(24バイト)のノンスを生成します。
40    $nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);
41    echo "ノンスを生成しました (長さ: " . strlen($nonce) . " バイト)\n";
42    echo "ノンスの生成完了。\n\n";
43
44    // 4. 平文を暗号化
45    // `sodium_crypto_stream_xchacha20()` を使用してデータを暗号化します。
46    // ここでは、ストリーム暗号として平文全体を暗号化しています。
47    $cipherText = sodium_crypto_stream_xchacha20($plainText, $nonce, $key);
48    echo "暗号化されたデータ (一部表示): " . substr(bin2hex($cipherText), 0, 40) . "...\n";
49    echo "暗号化されたデータの長さ: " . strlen($cipherText) . " バイト\n\n";
50
51    // 5. 暗号文を復号
52    // 暗号化時と全く同じ鍵とノンスを使用して、暗号化されたデータを復号します。
53    // ストリーム暗号は、暗号化と復号に同じ関数を使用します。
54    $decryptedText = sodium_crypto_stream_xchacha20($cipherText, $nonce, $key);
55    echo "復号された平文: \"" . $decryptedText . "\"\n";
56    echo "復号された平文の長さ: " . strlen($decryptedText) . " バイト\n\n";
57
58    // 6. 検証
59    // 復号されたデータが元の平文と一致するか確認します。
60    if ($plainText === $decryptedText) {
61        echo "✅ 検証成功: データは正しく暗号化および復号されました。\n";
62    } else {
63        echo "❌ 検証失敗: データの暗号化または復号に問題が発生しました。\n";
64    }
65    echo "\n-------------------------------------------------\n";
66}
67
68// サンプル関数の実行
69runXChaCha20EncryptionExample();

PHP 8のsodium_crypto_stream_xchacha20_keygen関数は、XChaCha20ストリーム暗号方式でデータを安全に保護するための秘密鍵を生成します。この関数は引数を取らず、戻り値として、32バイトのランダムな文字列(string型)である秘密鍵を返します。この秘密鍵は、データの暗号化と復号の両方に用いられる対称鍵です。

サンプルコードでは、まずこの関数で秘密鍵を生成します。次に、暗号化したい平文データを準備し、sodium_crypto_stream_xchacha20関数で暗号化に必要なノンス(Number Used Once)を安全に生成します。ノンスは毎回異なる値を用いることで、暗号化の安全性を高めます。生成された秘密鍵とノンスを使って平文データを暗号化し、暗号文を得ます。その後、同じ鍵とノンスを用いて暗号文を復号し、元の平文が正しく再現されることを検証しています。

sodium_crypto_stream_xchacha20_keygenは、PHPで強力な対称鍵暗号化システムを構築する出発点となる関数です。システムエンジニアが機密データを扱う際の基礎となるデータ保護技術の一例を示しており、鍵とノンスを適切に管理することで、安全なデータ送受信が可能になります。

sodium_crypto_stream_xchacha20_keygenで生成される鍵は極秘情報であり、外部への漏洩は深刻なセキュリティリスクとなります。鍵は絶対に表示したりログに出力したりせず、厳重に管理してください。ノンスは暗号化のたびに異なる値を生成することが極めて重要で、同じ鍵でノンスを再利用すると暗号の安全性が著しく低下します。ノンス自体は秘密である必要はありませんが、暗号文と一緒に管理してください。この機能を利用するには、PHPにSodium拡張が正しくインストールされ、有効になっている必要があります。サンプルコードは基本的な対称鍵暗号化の流れを示していますが、実運用では鍵の安全な保管方法や、データの改ざん検知も行える認証付き暗号化の利用も検討してください。

PHP Libsodium secretboxで暗号化・復号化する

1<?php
2
3/**
4 * Libsodiumのsodium_crypto_stream_xchacha20_keygen関数で生成した鍵と
5 * sodium_crypto_secretbox関数を組み合わせてメッセージを暗号化・復号化する例。
6 *
7 * sodium_crypto_stream_xchacha20_keygenで生成される鍵は32バイトであり、
8 * これはsodium_crypto_secretboxが期待する鍵の長さ(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)と一致するため、
9 * 両者を組み合わせて利用することが可能です。
10 */
11function encryptAndDecryptWithSodiumSecretboxUsingStreamKey(): void
12{
13    // 1. stream_xchacha20用の鍵を生成します。
14    // この鍵は、secretbox関数にも利用できます。
15    $key = sodium_crypto_stream_xchacha20_keygen();
16    echo "--- 鍵の生成 ---\n";
17    echo "生成された鍵の長さ: " . strlen($key) . " バイト (期待値: " . SODIUM_CRYPTO_SECRETBOX_KEYBYTES . " バイト)\n\n";
18
19    // 2. 暗号化するオリジナルのメッセージを準備します。
20    $originalMessage = 'これは重要な秘密のメッセージです。誰にも読まれないように暗号化します!';
21    echo "--- 暗号化 ---\n";
22    echo "元のメッセージ: " . $originalMessage . "\n";
23
24    // 3. SecretBoxに必須のノンセ(nonce、使い捨ての数)を生成します。
25    // ノンセは、同じ鍵で複数のメッセージを暗号化する際に、毎回異なるものを使用する必要があります。
26    // 同じ鍵とノンセの組み合わせを2度使ってはいけません。
27    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
28    echo "生成されたノンセの長さ: " . strlen($nonce) . " バイト (期待値: " . SODIUM_CRYPTO_SECRETBOX_NONCEBYTES . " バイト)\n\n";
29
30    // 4. メッセージを暗号化します。
31    // 引数: (メッセージ, ノンセ, 鍵)
32    $ciphertext = sodium_crypto_secretbox($originalMessage, $nonce, $key);
33    echo "暗号文の長さ: " . strlen($ciphertext) . " バイト\n\n";
34
35    // 5. 暗号文を復号化します。
36    // 復号化には、暗号化時とまったく同じ鍵とノンセが必要です。
37    // 鍵またはノンセが一つでも異なると復号に失敗します。
38    $decryptedMessage = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
39
40    if ($decryptedMessage === false) {
41        echo "--- 復号化失敗 ---\n";
42        echo "エラー: メッセージの復号化に失敗しました。鍵またはノンセが不正な可能性があります。\n";
43    } else {
44        echo "--- 復号化成功 ---\n";
45        echo "復号化されたメッセージ: " . $decryptedMessage . "\n";
46
47        // 6. オリジナルメッセージと復号化されたメッセージが一致するか確認します。
48        if ($originalMessage === $decryptedMessage) {
49            echo "結果: 元のメッセージと復号化されたメッセージは完全に一致します。\n";
50        } else {
51            echo "結果: 元のメッセージと復号化されたメッセージは一致しません!何かがおかしいです。\n";
52        }
53    }
54}
55
56// 関数を実行します。
57encryptAndDecryptWithSodiumSecretboxUsingStreamKey();
58
59?>

PHPのsodium_crypto_stream_xchacha20_keygen関数は、セキュアなデータ暗号化に用いられる秘密鍵を生成します。この関数は引数を一切取らず、戻り値として32バイトのバイナリ文字列形式の鍵を返します。生成された鍵は、主にLibreNaCLライブラリの機能を提供するsodium_crypto_secretboxsodium_crypto_secretbox_openといった関数と組み合わせて利用されます。例えば、sodium_crypto_secretbox関数では、この鍵とメッセージごとに異なる「ノンセ(nonce)」と呼ばれる使い捨ての値を用いてメッセージを暗号化し、機密性を保護します。復号化には、暗号化時と全く同じ鍵とノンセが必須であり、どちらか一つでも異なると復号に失敗します。特に、同じ鍵で複数のメッセージを暗号化する場合でも、ノンセは必ず毎回異なるものを生成して使用することが、暗号の安全性を維持するために極めて重要です。この関数を利用することで、安全な暗号通信の基盤となる鍵を手軽に生成できます。

sodium_crypto_stream_xchacha20_keygen関数で生成される鍵は、sodium_crypto_secretboxが要求する32バイトの鍵長と一致し、相互に利用できます。暗号化において最も重要なのはノンセ(nonce、使い捨ての数)の管理です。同じ鍵で複数のメッセージを暗号化する際は、毎回必ず異なるノンセを生成し使用してください。同じ鍵とノンセの組み合わせを二度使うことは、セキュリティを著しく低下させるため厳禁です。復号化には、暗号化時と全く同じ鍵とノンセが必要です。これらが一つでも異なると復号に失敗し、関数はfalseを返します。その際の適切なエラー処理を実装することが重要です。

関連コンテンツ

関連IT用語

関連プログラミング言語