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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_box_keypair_from_secretkey_and_publickey関数は、PHPのSodium拡張機能が提供する暗号化関連の関数で、指定された秘密鍵と公開鍵の各情報を結合し、認証付き暗号化(Crypto_box)で使用する新しい鍵ペアを生成する関数です。

Crypto_boxは、インターネット上での安全なメッセージ交換やデータ通信において、メッセージの内容を秘密にしつつ、同時にその内容が改ざんされていないことを保証するために利用される強力な暗号化技術です。この関数を使用することで、すでに生成済みで保持している秘密鍵のデータと公開鍵のデータをそれぞれ引数として渡すことで、それらを一つの「鍵ペア」としてまとめたデータを取得できます。

これにより、例えばプログラムの実行中に、別々に管理されている秘密鍵と公開鍵の情報から、Crypto_boxでの暗号化や復号化操作に必要な鍵ペアをその場で再構築して利用するといった用途に役立ちます。通常、新しい鍵ペアはsodium_crypto_box_keypair関数で生成されますが、この関数は既存の鍵データから鍵ペアを「再構成」する目的で利用されます。暗号化において非常に重要な情報を取り扱うため、秘密鍵の管理には細心の注意が必要です。

構文(syntax)

1<?php
2$secretKey = sodium_crypto_box_secretkey();
3$publicKey = sodium_crypto_box_publickey($secretKey);
4
5$keypair = sodium_crypto_box_keypair_from_secretkey_and_publickey($secretKey, $publicKey);

引数(parameters)

string $secret_key, string $public_key

  • string $secret_key: 秘密鍵を指定する文字列。この秘密鍵は、対応する公開鍵とともに、署名や暗号化に使用されます。
  • string $public_key: 公開鍵を指定する文字列。この公開鍵は、対応する秘密鍵とともに、署名や暗号化に使用されます。

戻り値(return)

string

指定された秘密鍵と公開鍵から、暗号化・復号化に使用できる鍵ペアのバイナリ文字列を返します。

サンプルコード

sodium_crypto_box_keypair_from_secretkey_and_publickey で共有鍵を導出する

1<?php
2
3/**
4 * libsodiumの`sodium_crypto_box_keypair_from_secretkey_and_publickey`関数の使用例。
5 *
6 * この関数は、自分自身の秘密鍵と相手の公開鍵を組み合わせて、
7 * 両者間でメッセージの暗号化・復号化に使用する「共通の秘密鍵」(shared secret key)
8 * を導出するための中間的なキーペアを生成します。
9 *
10 * システムエンジニアを目指す初心者にも分かりやすいように、各ステップをコメントで説明します。
11 * PHP 8 環境で実行することを想定しています。
12 */
13function demonstrateSodiumCryptoBoxKeypairDerivation(): void
14{
15    echo "--- libsodium `sodium_crypto_box_keypair_from_secretkey_and_publickey` 例 ---\n\n";
16
17    // --- ステップ1: 通信を行う2者(アリスとボブ)のキーペアをそれぞれ生成する ---
18    // 実際のシステムでは、これらのキーペアはそれぞれの当事者によって独立して生成され、
19    // 秘密鍵は厳重に保管されます。公開鍵は安全に交換することができます。
20
21    // アリスのキーペア生成
22    $aliceKeyPair = sodium_crypto_box_keypair();
23    $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeyPair); // アリス自身の秘密鍵
24    $alicePublicKey = sodium_crypto_box_publickey($aliceKeyPair);  // アリス自身の公開鍵
25
26    echo "アリスの秘密鍵 (hex): " . bin2hex($aliceSecretKey) . "\n";
27    echo "アリスの公開鍵 (hex): " . bin2hex($alicePublicKey) . "\n\n";
28
29    // ボブのキーペア生成
30    $bobKeyPair = sodium_crypto_box_keypair();
31    $bobSecretKey = sodium_crypto_box_secretkey($bobKeyPair); // ボブ自身の秘密鍵
32    $bobPublicKey = sodium_crypto_box_publickey($bobKeyPair);  // ボブ自身の公開鍵
33
34    echo "ボブの秘密鍵 (hex): " . bin2hex($bobSecretKey) . "\n";
35    echo "ボブの公開鍵 (hex): " . bin2hex($bobPublicKey) . "\n\n";
36
37    // --- ステップ2: `sodium_crypto_box_keypair_from_secretkey_and_publickey` を使用して
38    //                共有の秘密鍵を導出するための中間キーペアを生成する ---
39    // この関数は、片方の秘密鍵と、もう片方の公開鍵を組み合わせることで、
40    // 両者が共通の「共有秘密鍵」を生成できるようにします。
41
42    // アリスがボブとの通信のために、共有鍵導出用の中間キーペアを生成
43    // 使用するのは「アリス自身の秘密鍵」と「ボブの公開鍵」です。
44    $aliceToBobDerivedKeyPair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
45        $aliceSecretKey, // アリス自身の秘密鍵
46        $bobPublicKey    // ボブの公開鍵
47    );
48
49    echo "アリスがボブとのために導出した中間キーペア (hex): " . bin2hex($aliceToBobDerivedKeyPair) . "\n";
50    // この中間キーペアから秘密鍵部分を取り出すと、それがアリス側の「共有秘密鍵」になります。
51    $aliceSharedSecretKey = sodium_crypto_box_secretkey($aliceToBobDerivedKeyPair);
52    echo "アリスが導出した共有秘密鍵 (hex): " . bin2hex($aliceSharedSecretKey) . "\n\n";
53
54    // ボブがアリスとの通信のために、共有鍵導出用の中間キーペアを生成
55    // 使用するのは「ボブ自身の秘密鍵」と「アリスの公開鍵」です。
56    $bobToAliceDerivedKeyPair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
57        $bobSecretKey,    // ボブ自身の秘密鍵
58        $alicePublicKey   // アリスの公開鍵
59    );
60
61    echo "ボブがアリスとのために導出した中間キーペア (hex): " . bin2hex($bobToAliceDerivedKeyPair) . "\n";
62    // この中間キーペアから秘密鍵部分を取り出すと、それがボブ側の「共有秘密鍵」になります。
63    $bobSharedSecretKey = sodium_crypto_box_secretkey($bobToAliceDerivedKeyPair);
64    echo "ボブが導出した共有秘密鍵 (hex): " . bin2hex($bobSharedSecretKey) . "\n\n";
65
66    // --- ステップ3: 両者が導出した「共有秘密鍵」が同じであることを確認する ---
67    // Diffie-Hellman鍵交換の原理により、両者が導出した共有秘密鍵は厳密に同一であるべきです。
68    if ($aliceSharedSecretKey === $bobSharedSecretKey) {
69        echo "✅ 成功: アリスとボブがそれぞれ導出した共有秘密鍵は一致しました。\n";
70        echo "これで、両者はこの共通の鍵を使用して安全なメッセージのやり取りができます。\n";
71    } else {
72        echo "❌ エラー: 導出された共有秘密鍵が一致しませんでした。\n";
73    }
74
75    // --- 参考: `sodium_crypto_box_beforenm` 関数との関係 ---
76    // `sodium_crypto_box_beforenm` 関数は、同じ「共有秘密鍵」を直接生成するための関数です。
77    // 上記で`sodium_crypto_box_keypair_from_secretkey_and_publickey`から秘密鍵部分を抽出したものと、
78    // `sodium_crypto_box_beforenm`が返す結果は同一になります。
79    $aliceDirectSharedSecret = sodium_crypto_box_beforenm($bobPublicKey, $aliceSecretKey);
80    $bobDirectSharedSecret = sodium_crypto_box_beforenm($alicePublicKey, $bobSecretKey);
81
82    echo "\n(参考) `sodium_crypto_box_beforenm` で導出した共有秘密鍵 (アリス側) (hex): " . bin2hex($aliceDirectSharedSecret) . "\n";
83    echo "(参考) `sodium_crypto_box_beforenm` で導出した共有秘密鍵 (ボブ側) (hex): " . bin2hex($bobDirectSharedSecret) . "\n";
84
85    if ($aliceSharedSecretKey === $aliceDirectSharedSecret && $bobSharedSecretKey === $bobDirectSharedSecret) {
86        echo "✅ 成功: `sodium_crypto_box_keypair_from_secretkey_and_publickey` から得られた鍵と\n";
87        echo "           `sodium_crypto_box_beforenm` で直接生成された鍵は一致します。\n";
88    }
89}
90
91// デモンストレーション関数を実行
92demonstrateSodiumCryptoBoxKeypairDerivation();
93

sodium_crypto_box_keypair_from_secretkey_and_publickey関数は、PHPのlibsodium拡張機能が提供する暗号化関数の一つです。この関数は、自分自身の秘密鍵通信相手の公開鍵を組み合わせて、両者間でメッセージの暗号化や復号化に使用する「共通の秘密鍵(Shared Secret Key)」を導出するための「中間キーペア」を生成することを目的としています。

引数としては、$secret_keyに「自身の秘密鍵」を、$public_keyに「通信相手の公開鍵」をそれぞれstring型で渡します。この組み合わせによって、Diffie-Hellman鍵交換の原理に基づき、セキュリティを確保しながら共通の鍵を生成するプロセスの中間段階を構築します。

関数の戻り値は、生成された中間キーペアを表すstring型のデータです。この戻り値から、さらにsodium_crypto_box_secretkey関数を用いることで、実際に使用する共通の秘密鍵を抽出することができます。この共通の秘密鍵は、通信を行う両者がそれぞれ独立して導出し、その結果が一致することで安全な通信路が確立されます。

サンプルコードでは、アリスとボブという二者が、お互いの秘密鍵と公開鍵を使って、安全に共通の秘密鍵を導出する一連の流れが示されており、これにより秘匿性の高い通信を実現するための基盤がどのように作られるかを確認できます。

sodium_crypto_box_keypair_from_secretkey_and_publickey関数は、自分自身の秘密鍵と通信相手の公開鍵を組み合わせ、両者間でメッセージ暗号化に使用する「共有秘密鍵」を導出するための中間的なキーペアを生成します。引数の$secret_keyには必ず自身の秘密鍵を、$public_keyには相手の公開鍵を適切に指定することが重要です。これらを誤ると意図しない結果となるため、鍵の役割を明確に理解してください。この関数が直接返すのは共有秘密鍵ではなく、そこからsodium_crypto_box_secretkey()関数を用いて共有秘密鍵を抽出します。生成した秘密鍵は厳重に保管し、外部への漏洩を防ぐことがセキュリティ上極めて重要です。なお、共有秘密鍵を直接生成したい場合は、sodium_crypto_box_beforenm関数も利用可能です。

sodium_crypto_box 鍵ペアを生成する

1<?php
2
3// Sodium拡張が利用可能か確認します。
4// システムエンジニアを目指す方にとって、必要な拡張機能が有効か確認することは重要です。
5if (!extension_loaded('sodium')) {
6    exit('エラー: Sodium拡張機能が有効になっていません。php.iniで有効にしてください。');
7}
8
9/**
10 * sodium_crypto_box_keypair_from_secretkey_and_publickey の使用例。
11 *
12 * この関数は、Diffie-Hellman鍵共有の原則に基づき、
13 * あるユーザーの秘密鍵と別のユーザーの公開鍵から、
14 * 共有の「ボックス」暗号化/復号化に必要なキーペアを生成します。
15 * 主にナトリウム(Sodium)ライブラリの `sodium_crypto_box` 関数での利用を目的とします。
16 */
17function demonstrateSodiumBoxKeypairFromKeys(): void
18{
19    echo "--- sodium_crypto_box_keypair_from_secretkey_and_publickey の使用例 ---\n\n";
20
21    try {
22        // 1. ユーザーA(例: アリス)の鍵ペアを生成します。
23        // sodium_crypto_box_keypair() は、秘密鍵と公開鍵を結合したバイナリ文字列を返します。
24        $aliceKeypair = sodium_crypto_box_keypair();
25        $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeypair); // アリスの秘密鍵を抽出
26        $alicePublicKey = sodium_crypto_box_publickey($aliceKeypair); // アリスの公開鍵を抽出
27
28        echo "アリスの秘密鍵 (Hex): " . bin2hex($aliceSecretKey) . "\n";
29        echo "アリスの公開鍵 (Hex): " . bin2hex($alicePublicKey) . "\n\n";
30
31        // 2. ユーザーB(例: ボブ)の鍵ペアを生成します。
32        // 実際には、ボブの公開鍵は安全な方法でアリスに共有されます。
33        $bobKeypair = sodium_crypto_box_keypair();
34        $bobSecretKey = sodium_crypto_box_secretkey($bobKeypair); // ボブの秘密鍵を抽出
35        $bobPublicKey = sodium_crypto_box_publickey($bobKeypair); // ボブの公開鍵を抽出
36
37        echo "ボブの秘密鍵 (Hex): " . bin2hex($bobSecretKey) . "\n";
38        echo "ボブの公開鍵 (Hex): " . bin2hex($bobPublicKey) . "\n\n";
39
40        // 3. アリス側で、アリス自身の秘密鍵とボブの公開鍵を使用して、共有キーペアを生成します。
41        // このキーペアは、アリスがボブに暗号化されたメッセージを送る際に使用できます。
42        $aliceToBobSharedKeypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
43            $aliceSecretKey,
44            $bobPublicKey
45        );
46
47        echo "アリスからボブへの共有キーペア (Hex): " . bin2hex($aliceToBobSharedKeypair) . "\n";
48        // 生成された共有キーペアから、実際に暗号化に使われる「共有秘密鍵」を抽出できます。
49        $aliceGeneratedSharedSecretKey = sodium_crypto_box_secretkey($aliceToBobSharedKeypair);
50        echo "アリス側で抽出された共有秘密鍵 (Hex): " . bin2hex($aliceGeneratedSharedSecretKey) . "\n\n";
51
52        // 4. ボブ側で、ボブ自身の秘密鍵とアリスの公開鍵を使用して、共有キーペアを生成します。
53        // このキーペアは、ボブがアリスから受け取ったメッセージを復号化したり、アリスに暗号化されたメッセージを送る際に使用できます。
54        $bobToAliceSharedKeypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
55            $bobSecretKey,
56            $alicePublicKey
57        );
58
59        echo "ボブからアリスへの共有キーペア (Hex): " . bin2hex($bobToAliceSharedKeypair) . "\n";
60        // ボブ側で生成された共有キーペアから、共有秘密鍵を抽出します。
61        $bobGeneratedSharedSecretKey = sodium_crypto_box_secretkey($bobToAliceSharedKeypair);
62        echo "ボブ側で抽出された共有秘密鍵 (Hex): " . bin2hex($bobGeneratedSharedSecretKey) . "\n\n";
63
64        // 5. Diffie-Hellman鍵共有の性質により、両者で生成された「共有秘密鍵」は同じになります。
65        // これが安全な通信の基盤となります。
66        if ($aliceGeneratedSharedSecretKey === $bobGeneratedSharedSecretKey) {
67            echo "結果: アリスとボブの両者で生成された共有秘密鍵は一致しました。\n";
68            echo "これにより、安全な暗号化通信の準備が整いました。\n";
69        } else {
70            echo "エラー: 共有秘密鍵が一致しません。鍵共有に問題が発生しました。\n";
71        }
72
73    } catch (SodiumException $e) {
74        // Sodium拡張機能に関連するエラーが発生した場合の処理
75        echo "Sodiumエラーが発生しました: " . $e->getMessage() . "\n";
76    } catch (Exception $e) {
77        // その他の予期せぬエラーが発生した場合の処理
78        echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n";
79    }
80}
81
82// 関数を実行して、サンプルコードの動作を確認します。
83demonstrateSodiumBoxKeypairFromKeys();

sodium_crypto_box_keypair_from_secretkey_and_publickey関数は、PHPのSodium拡張機能が提供する暗号化機能の一つです。この関数は、Diffie-Hellman鍵共有という安全な通信を実現するための技術に基づき、ユーザー自身の秘密鍵と通信相手の公開鍵を組み合わせて、共有の「ボックス」暗号化/復号化に必要なキーペアを生成します。

引数としては、$secret_keyに自身の秘密鍵(他人に知られてはいけない鍵)、$public_keyに通信相手の公開鍵(相手から受け取った鍵)を指定します。これらの鍵は、sodium_crypto_box_keypair()などの関数で事前に生成されたバイナリ文字列である必要があります。関数は、これら二つの鍵から計算された、メッセージの暗号化・復号化に利用するバイナリ形式の「共有キーペア」を文字列として返します。この共有キーペアから、さらにsodium_crypto_box_secretkey()関数を使って、実際にメッセージの暗号化・復号化に使われる「共有秘密鍵」を抽出できます。

サンプルコードでは、アリスとボブという二人が、お互いの秘密鍵と相手の公開鍵を使ってそれぞれ共有キーペアを生成しています。Diffie-Hellman鍵共有の性質により、アリス側で生成された共有秘密鍵とボブ側で生成された共有秘密鍵は完全に一致します。この共通の秘密鍵が、両者間で安全に暗号化されたメッセージを送受信するための基盤となるのです。システムエンジニアにとって、このような安全な通信プロトコルの理解は非常に重要です。

sodium_crypto_box_keypair_from_secretkey_and_publickey関数を利用する際は、まずPHPのSodium拡張機能が有効になっているか確認が必要です。この関数は、自身の秘密鍵と通信相手の公開鍵を組み合わせて、安全な通信のための「共有キーペア」を生成します。最も重要な点は、この方法で両者が生成した共有秘密鍵が必ず一致することです。これにより、メッセージの暗号化と復号化が可能になります。自身の秘密鍵はセキュリティ上極めて重要であり、絶対に漏洩させてはならず、厳重に管理してください。また、予期せぬエラーが発生した場合に備え、try-catchブロックでSodiumExceptionなどを適切に捕捉し、エラー処理を実装することが堅牢なシステム構築には不可欠です。

関連コンテンツ

関連プログラミング言語