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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_box_publickey_from_secretkey関数は、非対称暗号化通信に利用される公開鍵を、対応する秘密鍵から生成する関数です。この関数はPHPのSodium拡張機能の一部であり、高信頼性の暗号化ライブラリであるLibsodiumの機能を提供します。

セキュアなデータ交換や認証のために、非対称暗号(公開鍵暗号)は広く利用されます。非対称暗号では、データを暗号化するための「公開鍵」と、そのデータを復号化するための「秘密鍵」がペアとして存在します。本関数は、既に生成されている秘密鍵から、それと対になる公開鍵を安全かつ確実に導き出すために使用されます。

具体的には、この関数は引数として、事前に生成された秘密鍵をバイナリ文字列の形式で受け取ります。そして、その秘密鍵に対応する公開鍵をバイナリ文字列として返します。この生成された公開鍵は、暗号化通信を行う相手に安全に共有することが可能です。しかし、元となる秘密鍵は非常に重要であり、厳重に管理され、決して他者に漏洩させてはなりません。公開鍵と秘密鍵のペアが正しく管理されることで、データの機密性、完全性、そして認証が保証されます。

この関数は、セキュアなメッセージング、API認証、データ署名など、セキュリティが求められる様々なアプリケーションやシステムにおいて、鍵管理の重要な一端を担います。

構文(syntax)

1<?php
2$secretKey = sodium_crypto_box_secretkey();
3$publicKey = sodium_crypto_box_publickey_from_secretkey($secretKey);

引数(parameters)

string $secret_key

  • string $secret_key: 秘密鍵を指定する文字列。この秘密鍵から対応する公開鍵が生成されます。

戻り値(return)

string

指定された秘密鍵から生成された公開鍵を文字列形式で返します。

サンプルコード

sodium_crypto_box_publickey_from_secretkeyで公開鍵を導出する

1<?php
2
3/**
4 * Libsodiumのシークレットキーから公開鍵を導出するサンプルコード。
5 *
6 * sodium_crypto_box_publickey_from_secretkey() 関数は、
7 * 与えられたシークレットキー(秘密鍵)から対応する公開鍵を導出します。
8 * これは、秘密鍵だけを安全に保管し、必要に応じて公開鍵を再生成したい場合に特に有用です。
9 *
10 * この関数は、PHPのsodium拡張機能の一部です。
11 */
12function demonstratePublicKeyDerivation(): void
13{
14    // sodium拡張がロードされているか確認します。
15    // この拡張がないと、sodium関連の関数は利用できません。
16    if (!extension_loaded('sodium')) {
17        echo "エラー: 'sodium' 拡張がロードされていません。PHP設定で有効にしてください。\n";
18        return;
19    }
20
21    echo "--- sodium_crypto_box_publickey_from_secretkey() の使用例 ---\n\n";
22
23    // 1. 新しい Libsodium キーペアを生成します。
24    // sodium_crypto_box_keypair() は、公開鍵と秘密鍵の両方を含む単一の文字列を返します。
25    $keypair = sodium_crypto_box_keypair();
26    echo "1. 新しいキーペアを生成しました。\n";
27
28    // 2. 生成されたキーペアから秘密鍵を抽出します。
29    // sodium_crypto_box_secretkey() はキーペアから秘密鍵の部分を取り出します。
30    $secretKey = sodium_crypto_box_secretkey($keypair);
31    echo "2. キーペアから秘密鍵を抽出しました (バイナリデータ)。\n";
32
33    // 3. 生成されたキーペアから元の公開鍵を抽出します。
34    // sodium_crypto_box_publickey() はキーペアから公開鍵の部分を取り出します。
35    $originalPublicKey = sodium_crypto_box_publickey($keypair);
36    echo "3. キーペアから元の公開鍵を抽出しました (バイナリデータ)。\n\n";
37
38    // 4. 抽出した秘密鍵から公開鍵を導出します。
39    // ここで今回の主役である sodium_crypto_box_publickey_from_secretkey() 関数を使用します。
40    // 秘密鍵のみを使って、対応する公開鍵を計算します。
41    $derivedPublicKey = sodium_crypto_box_publickey_from_secretkey($secretKey);
42    echo "4. 抽出した秘密鍵から新しい公開鍵を導出しました。\n\n";
43
44    // 5. 元の公開鍵と導出された公開鍵が一致するか検証します。
45    // 2つの公開鍵が同一であれば、関数が正しく動作していることを示します。
46    if ($originalPublicKey === $derivedPublicKey) {
47        echo "5. 検証成功: 元の公開鍵と秘密鍵から導出された公開鍵は一致します。\n";
48        echo "   これにより、sodium_crypto_box_publickey_from_secretkey() が正しく機能していることが確認できました。\n";
49    } else {
50        echo "5. 検証失敗: 元の公開鍵と導出された公開鍵が一致しません。\n";
51    }
52
53    echo "\n----------------------------------------------------------------\n";
54}
55
56// サンプルコードを実行します。
57demonstratePublicKeyDerivation();
58
59?>

PHPのsodium_crypto_box_publickey_from_secretkey関数は、暗号化に用いられるLibSodiumライブラリの一部で、指定された秘密鍵(シークレットキー)から対応する公開鍵を導出するために使用されます。この関数は、引数としてバイナリ文字列の秘密鍵を受け取ります。そして、その秘密鍵から計算された公開鍵をバイナリ文字列として返します。

システムにおいて、秘密鍵だけを安全に管理し、必要な時にだけ公開鍵を再生成したい場合に特に有用です。例えば、サンプルコードでは、まずsodium_crypto_box_keypair()で新しいキーペアを生成し、そこから秘密鍵を抽出します。その後、抽出した秘密鍵を本関数に渡すことで、元のキーペアに含まれていた公開鍵とまったく同じ公開鍵を導出できることを示しています。これにより、秘密鍵が正しければ公開鍵を常に再生成できることが保証されます。

この機能を利用するためには、PHP環境でsodium拡張が有効になっている必要があります。有効でない場合、関連する関数は利用できませんので、PHPの設定をご確認ください。

このコードを利用する際は、PHPのsodium拡張が有効になっているか、事前に確認することが必須です。有効でない場合、この関数は利用できません。sodium_crypto_box_publickey_from_secretkey関数は秘密鍵から対応する公開鍵を導出しますが、秘密鍵は情報漏洩のリスクを避けるため、決して外部に公開せず厳重に管理してください。また、引数や戻り値の鍵データはバイナリ文字列です。データベースへの保存やログ出力の際には、Base64などで適切にエンコードすることを推奨します。この関数は、秘密鍵のみを安全に保管し、必要に応じて公開鍵を再生成したい場合に特に有用です。

PHP Libsodium: 秘密鍵から公開鍵を導出する

1<?php
2
3// Libsodium拡張機能が利用可能か確認します
4if (!extension_loaded('sodium')) {
5    die('PHP Sodium extension is not loaded. Please enable it.');
6}
7
8/**
9 * Libsodiumの公開鍵暗号(Box)機能を使って、秘密鍵から公開鍵を導出し、
10 * その鍵ペアでメッセージの暗号化・復号化を行うサンプルです。
11 *
12 * sodium_crypto_box_publickey_from_secretkey 関数は、
13 * 与えられた秘密鍵に対応する公開鍵を計算して返します。
14 * これは、秘密鍵が既に存在する場合に、それに対応する公開鍵を再生成する用途などで利用されます。
15 *
16 * PHP 8の推奨コーディングスタイルに従い、単一の関数として実装されています。
17 *
18 * 【キーワード: sodium_crypto_secretbox について】
19 * Libsodiumは、この例で示す公開鍵暗号 (sodium_crypto_box シリーズ) の他に、
20 * sodium_crypto_secretbox のような共有鍵暗号機能も提供しています。
21 * sodium_crypto_secretbox は単一の共有秘密鍵で暗号化・復号化を行うため、
22 * 鍵の管理方法や利用シナリオが公開鍵暗号とは異なります。
23 * このサンプルでは、リファレンス情報に基づき公開鍵暗号の鍵生成に焦点を当てています。
24 */
25function demonstrateSodiumPublicKeyGenerationAndBoxEncryption(): void
26{
27    echo "--- Libsodium 公開鍵暗号 (Box) の例 ---\n";
28
29    // 1. 公開鍵と秘密鍵を含む鍵ペアを生成します。
30    // sodium_crypto_box_keypair() は、ECDH (Elliptic Curve Diffie-Hellman) に基づく
31    // 公開鍵と秘密鍵が結合された単一の文字列を生成します。
32    $keypair = sodium_crypto_box_keypair();
33
34    // 生成された鍵ペアから秘密鍵と公開鍵をそれぞれ抽出します。
35    $secret_key_extracted = sodium_crypto_box_secretkey($keypair);
36    $public_key_extracted = sodium_crypto_box_publickey($keypair);
37
38    echo "生成された秘密鍵 (一部表示): " . bin2hex(substr($secret_key_extracted, 0, 8)) . "...\n";
39    echo "生成された公開鍵 (一部表示): " . bin2hex(substr($public_key_extracted, 0, 8)) . "...\n";
40
41    // 2. リファレンス情報の関数 sodium_crypto_box_publickey_from_secretkey を使用して、
42    // 抽出した秘密鍵から公開鍵を導出します。
43    // この関数は、引数として秘密鍵 ($secret_key_extracted) のみを受け取ります。
44    $public_key_derived = sodium_crypto_box_publickey_from_secretkey($secret_key_extracted);
45
46    echo "秘密鍵から導出された公開鍵 (一部表示): " . bin2hex(substr($public_key_derived, 0, 8)) . "...\n";
47
48    // 3. 導出された公開鍵が、鍵ペアから直接抽出した元の公開鍵と一致することを確認します。
49    if ($public_key_extracted === $public_key_derived) {
50        echo "✅ 秘密鍵から導出された公開鍵は、元の鍵ペアの公開鍵と一致します。\n";
51    } else {
52        echo "❌ エラー: 公開鍵が一致しません。\n";
53        return;
54    }
55
56    echo "\n--- 公開鍵暗号 (Box) を使用したメッセージの送受信例 ---\n";
57
58    // 別のユーザー(例: Bob)の鍵ペアを生成します。
59    // この鍵ペアは、上記の鍵ペア(例: Alice)とは独立しています。
60    $bob_keypair = sodium_crypto_box_keypair();
61    $bob_secret_key = sodium_crypto_box_secretkey($bob_keypair);
62    $bob_public_key = sodium_crypto_box_publickey($bob_keypair);
63
64    // 今回のユーザー(Alice)の鍵は上記で生成したものを使用します。
65    $alice_secret_key = $secret_key_extracted;
66    $alice_public_key = $public_key_extracted;
67
68    $message = "これはAliceからBobへの秘密のメッセージです。";
69    // ナンス (Nonce) は、各暗号化操作で一度だけ使用されるランダムな値です。
70    // 予測不可能である必要があり、再利用してはいけません。
71    $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
72
73    echo "元のメッセージ: " . $message . "\n";
74
75    // AliceがBobにメッセージを暗号化して送信します。
76    // 暗号化には、送信者(Alice)の秘密鍵と、受信者(Bob)の公開鍵を使用します。
77    $encrypted_message = sodium_crypto_box(
78        $message,
79        $nonce,
80        $bob_public_key,   // 受信者Bobの公開鍵
81        $alice_secret_key  // 送信者Aliceの秘密鍵
82    );
83
84    echo "暗号化されたメッセージ (一部表示): " . bin2hex(substr($encrypted_message, 0, 16)) . "...\n";
85
86    // BobがAliceからのメッセージを復号化します。
87    // 復号化には、受信者(Bob)の秘密鍵と、送信者(Alice)の公開鍵を使用します。
88    $decrypted_message = sodium_crypto_box_open(
89        $encrypted_message,
90        $nonce,
91        $alice_public_key, // 送信者Aliceの公開鍵
92        $bob_secret_key    // 受信者Bobの秘密鍵
93    );
94
95    // 復号化されたメッセージが元のメッセージと一致するか確認します。
96    if ($decrypted_message === $message) {
97        echo "✅ メッセージは正常に復号化されました。\n";
98        echo "復号化されたメッセージ: " . $decrypted_message . "\n";
99    } else {
100        echo "❌ エラー: メッセージの復号化に失敗しました。\n";
101    }
102}
103
104// 上記の関数を実行して、デモンストレーションを開始します。
105demonstrateSodiumPublicKeyGenerationAndBoxEncryption();
106

このサンプルコードは、PHPのLibsodium拡張機能を利用し、公開鍵暗号における秘密鍵から公開鍵を導出するプロセスと、その鍵ペアを用いたメッセージの暗号化・復号化の基本を示しています。

核となるsodium_crypto_box_publickey_from_secretkey関数は、引数として一つの秘密鍵(string $secret_key)を受け取ります。この関数は、与えられた秘密鍵に対応する公開鍵を計算し、string型の公開鍵データとして返します。これは、既に秘密鍵が存在する場合に、その秘密鍵に紐づく公開鍵を確実に再生成したい場面で活用されます。

コードではまず、sodium_crypto_box_keypair()で公開鍵と秘密鍵を含む鍵ペアを生成し、そこから秘密鍵を抽出します。次に、抽出した秘密鍵をsodium_crypto_box_publickey_from_secretkey関数に渡し、対応する公開鍵を導出しています。そして、この導出された公開鍵が、最初に生成した鍵ペアから抽出した公開鍵と一致することを検証し、関数の正確性を示しています。

さらに、生成および導出された鍵ペアを用いて、AliceとBobという二者間でのメッセージの暗号化(sodium_crypto_box)と復号化(sodium_crypto_box_open)の例を通じて、公開鍵暗号の実際の利用方法を具体的に示しています。Libsodiumにはsodium_crypto_secretboxのような共有鍵暗号機能もありますが、このサンプルはsodium_crypto_boxシリーズに焦点を当てています。

このサンプルコードを実行するには、PHPのLibsodium拡張機能が有効になっていることが必須です。秘密鍵はシステムのセキュリティにおいて最も重要な要素であり、絶対に外部に漏洩させないよう厳重に管理してください。公開鍵は秘密鍵から導出可能ですが、鍵ペアのゼロからの生成はsodium_crypto_box_keypair()で行います。暗号化に用いるナンスは、毎回random_bytesなどで新しく生成し、決して再利用してはいけません。再利用するとセキュリティが著しく低下します。また、sodium_crypto_boxは公開鍵暗号、sodium_crypto_secretboxは共有鍵暗号と、異なる目的で使用されますので混同しないよう注意が必要です。暗号化と復号化で、送信者と受信者のどちらの秘密鍵・公開鍵を引数に指定するのかを正しく理解し、使い分けることが大切です。

関連コンテンツ

関連プログラミング言語