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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_sign_keypair_from_secretkey_and_publickey関数は、Ed25519アルゴリズムに基づくデジタル署名に使用する鍵ペアを、既存の秘密鍵と公開鍵から再構成する関数です。この関数は、既に個別に生成されている署名用の秘密鍵と対応する公開鍵を受け取り、それらを統合して、デジタル署名を行うための完全な鍵ペアとして利用可能な形式で返します。デジタル署名では、データの改ざん防止や送信者の認証を目的として、秘密鍵と公開鍵が一体となった「鍵ペア」が用いられます。しかし、鍵の管理や配布の都合上、秘密鍵と公開鍵が別々の形式で提供されることがあります。本関数は、そうした状況において、提供された秘密鍵と公開鍵を安全に結合し、sodium_crypto_sign()などの署名操作関数で使用できる鍵ペアを生成します。具体的には、第一引数に署名用の秘密鍵(シークレットキー)、第二引数に対応する公開鍵(パブリックキー)をバイナリ文字列として渡します。そして、これらの情報を含む新しい鍵ペアのバイナリ文字列が戻り値として返されます。この鍵ペアは、メッセージへの署名生成や、既存の署名の検証など、一連の暗号署名処理の基礎となります。暗号鍵の取り扱いはセキュリティ上非常に重要ですので、この関数を利用する際には、入力する秘密鍵と公開鍵の安全性と正確性を十分に確認してください。

構文(syntax)

1sodium_crypto_sign_keypair_from_secretkey_and_publickey(string $secret_key, string $public_key);

引数(parameters)

string $secret_key, string $public_key

  • string $secret_key: 署名生成に用いる秘密鍵を指定する文字列
  • string $public_key: 署名検証に用いる公開鍵を指定する文字列

戻り値(return)

string

指定された公開鍵と秘密鍵から、符号化された署名鍵ペアを文字列として返します。

サンプルコード

署名鍵ペアからBox鍵ペアを導出し暗号化・復号する

1<?php
2
3/**
4 * Libsodiumの署名とボックス機能の連携を示すサンプル
5 *
6 * sodium_crypto_sign_keypair_from_secretkey_and_publickey() を使用して署名キーペアを再構築し、
7 * その後、署名キーペアから暗号化(ボックス)キーペアを導出し、メッセージの暗号化と復号化を行います。
8 *
9 * システムエンジニアを目指す初心者向けに、各ステップの目的を簡潔に説明します。
10 */
11function demonstrateSodiumFeatures(): void
12{
13    // --- Libsodium 署名キーペア生成と再構築のデモンストレーション ---
14    echo "--- Libsodium 署名キーペア生成と再構築のデモンストレーション ---\n";
15
16    // 1. Ed25519署名用の鍵ペアを生成します。
17    //    この鍵ペアは、メッセージの署名と検証に使用されます。
18    $signKeypair = sodium_crypto_sign_keypair();
19    echo "署名キーペアを生成しました。\n";
20
21    // 2. 生成された鍵ペアから秘密鍵と公開鍵を抽出します。
22    //    秘密鍵は署名者が所有し、公開鍵は検証者が所有します。
23    $signSecretKey = sodium_crypto_sign_secretkey($signKeypair);
24    $signPublicKey = sodium_crypto_sign_publickey($signKeypair);
25    echo "秘密鍵と公開鍵を抽出しました。\n";
26
27    // 3. 抽出した秘密鍵と公開鍵から、元の署名鍵ペアを再構築します。
28    //    これは、鍵が別々に保存されている場合や、特定の形式で鍵ペアを再構成する際に有用です。
29    $reconstructedSignKeypair = sodium_crypto_sign_keypair_from_secretkey_and_publickey(
30        $signSecretKey,
31        $signPublicKey
32    );
33    echo "抽出した秘密鍵と公開鍵から、署名キーペアを再構築しました。\n";
34
35    // 補足: 再構築された鍵ペアが元の鍵ペアと同一であることを確認できます。
36    // (バイナリ比較で同一になります)
37    if ($reconstructedSignKeypair === $signKeypair) {
38        echo " -> 再構築されたキーペアは元のキーペアと一致します。\n";
39    } else {
40        echo " -> エラー: 再構築されたキーペアが元のキーペアと一致しません。\n";
41        // 異常終了
42        return;
43    }
44
45    echo "\n--- Libsodium 暗号化(Box)機能のデモンストレーション ---\n";
46
47    // 4. Ed25519署名用の秘密鍵と公開鍵から、Curve25519暗号化(Box)用の鍵ペアを導出します。
48    //    Liblibsodiumは、署名と暗号化で異なる種類の鍵を使用しますが、これらの関数で互換性を持たせることができます。
49    $boxSecretKey = sodium_crypto_sign_secretkey_to_curve25519($signSecretKey);
50    $boxPublicKey = sodium_crypto_sign_publickey_to_curve25519($signPublicKey);
51    echo "署名用の鍵から、Box暗号化用の鍵ペアを導出しました。\n";
52
53    // 5. 暗号化するメッセージを定義します。
54    $message = 'システムエンジニアの皆さん、Liblibsodiumは素晴らしい!';
55    echo "元のメッセージ: \"{$message}\"\n";
56
57    // 6. 暗号化に使用するワンタイムナンス(Nonce: Number used once)を生成します。
58    //    ナンスはメッセージごとに異なっている必要があり、暗号文と一緒に送信されます。
59    //    同じ鍵ペアで複数のメッセージを暗号化する場合でも、常に異なるナンスを使用してください。
60    $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
61    echo "ナンスを生成しました。\n";
62
63    // 7. メッセージを暗号化します。
64    //    sodium_crypto_box() は、Diffie-Hellman鍵交換に基づき、指定された公開鍵(受信者)と秘密鍵(送信者)を使用して
65    //    メッセージを暗号化し、改ざんを検知するための認証情報も付加します。
66    //    引数順: sodium_crypto_box(メッセージ, ナンス, 受信者の公開鍵, 送信者の秘密鍵)
67    //    ここでは自分自身の鍵ペアで暗号化・復号化の例を示すため、両方の引数に自身の鍵を使用します。
68    $ciphertext = sodium_crypto_box($message, $nonce, $boxPublicKey, $boxSecretKey);
69    echo "メッセージを暗号化しました。\n";
70    // 通常、暗号文はバイナリデータなのでそのまま表示すると読めない文字になります。
71    // echo "暗号文 (Base64エンコード): " . base64_encode($ciphertext) . "\n";
72
73    // 8. 暗号化されたメッセージを復号化します。
74    //    sodium_crypto_box_open() は、対応する秘密鍵(受信者)と公開鍵(送信者)、ナンスを使ってメッセージを復号化します。
75    //    復号に失敗したり、メッセージが改ざんされている場合は false を返します。
76    //    引数順: sodium_crypto_box_open(暗号文, ナンス, 送信者の公開鍵, 受信者の秘密鍵)
77    $decryptedMessage = sodium_crypto_box_open($ciphertext, $nonce, $boxPublicKey, $boxSecretKey);
78    
79    if ($decryptedMessage === false) {
80        echo "エラー: メッセージの復号に失敗したか、改ざんされています。\n";
81    } else {
82        echo "メッセージを復号しました。\n";
83        echo "復号されたメッセージ: \"{$decryptedMessage}\"\n";
84
85        // 復号されたメッセージが元のメッセージと一致することを確認します。
86        if ($decryptedMessage === $message) {
87            echo " -> 復号されたメッセージは元のメッセージと一致します。成功!\n";
88        } else {
89            echo " -> エラー: 復号されたメッセージが元のメッセージと一致しません。\n";
90        }
91    }
92}
93
94// サンプル関数を実行します
95demonstrateSodiumFeatures();
96
97?>

sodium_crypto_sign_keypair_from_secretkey_and_publickey関数は、Liblibsodiumライブラリにおいて、すでに存在する署名用の秘密鍵と公開鍵から、完全な署名キーペアを再構築するために使用されます。この関数は、$secret_key引数には署名用の秘密鍵を、$public_key引数には対応する署名用の公開鍵を文字列として受け取ります。そして、これら二つの鍵を組み合わせ、新しい署名キーペア(文字列形式)を戻り値として返します。

この機能は、秘密鍵と公開鍵が別々に保存されている状況で、それらを再びまとめて完全なキーペアとして扱いたい場合に特に有用です。例えば、セキュリティ上の理由で鍵の管理方法を分けたり、異なるシステム間で鍵の情報を連携させたりする際に利用できます。

提供されたサンプルコードでは、まず新しい署名キーペアを生成し、その秘密鍵と公開鍵を個別に抽出します。その後、このsodium_crypto_sign_keypair_from_secretkey_and_publickey関数を用いて、抽出した秘密鍵と公開鍵から元のキーペアを正確に再構築できることを実証しています。さらに、サンプルコードでは署名用の鍵から暗号化(Box)用の鍵を導出し、メッセージの暗号化と復号化を行う例も示しており、本関数がLiblibsodiumのセキュリティ機能全般における鍵管理の基盤となることを理解するのに役立ちます。

PHPのLibsodiumを用いたこのサンプルコードでは、鍵の「再構築」と「導出」、そしてBox暗号化の基本を示しています。sodium_crypto_sign_keypair_from_secretkey_and_publickeyは、既存の秘密鍵と公開鍵から完全なキーペアを再構築する際に使用し、新しい鍵を生成する機能ではない点にご注意ください。最も重要なのは、秘密鍵は決して外部に漏らさないよう厳重に管理することです。また、sodium_crypto_boxで暗号化する際に使用するナンス(Nonce)は、同じ鍵ペアであってもメッセージごとに必ず異なるものを生成し、使い回さないでください。ナンスの重複は深刻なセキュリティ脆弱性につながります。sodium_crypto_box_openの復号結果がfalseでないか常に確認し、メッセージの改ざんや復号失敗に適切に対応することも重要です。

Libsodium署名鍵ペアを再構築する

1<?php declare(strict_types=1);
2
3/**
4 * Libsodiumの署名鍵ペアの再構築を実演するサンプルコード。
5 *
6 * sodium_crypto_sign_keypair_from_secretkey_and_publickey() 関数は、
7 * 既に持っている秘密鍵と公開鍵から、完全な署名鍵ペアを再構築するために使用されます。
8 * これは、秘密鍵と公開鍵を別々に管理し、必要に応じて結合して
9 * 完全な鍵ペアとして利用するシナリオで役立ちます。
10 */
11function demonstrateSodiumSignKeypairReconstruction(): void
12{
13    // Libsodium拡張がPHPにロードされているかを確認します。
14    // この拡張がないと、以下の関数は動作しません。
15    if (!extension_loaded('sodium')) {
16        echo "エラー: Libsodium拡張がロードされていません。PHPの設定を確認してください。" . PHP_EOL;
17        return;
18    }
19
20    echo "--- Libsodium 署名鍵ペア再構築デモ ---" . PHP_EOL . PHP_EOL;
21
22    // 1. まず、新しい署名鍵ペアを生成します。
23    // sodium_crypto_sign_keypair() は、秘密鍵と公開鍵の両方を含む完全な鍵ペアを生成します。
24    $originalKeypair = sodium_crypto_sign_keypair();
25    echo "1. 生成されたオリジナル鍵ペア (バイナリのHEX表現): " . bin2hex($originalKeypair) . PHP_EOL;
26
27    // 2. 生成された鍵ペアから秘密鍵と公開鍵をそれぞれ抽出します。
28    // sodium_crypto_sign_secretkey() で鍵ペアから秘密鍵の部分を取り出します。
29    $secretKey = sodium_crypto_sign_secretkey($originalKeypair);
30    echo "2. 抽出された秘密鍵 (バイナリのHEX表現): " . bin2hex($secretKey) . PHP_EOL;
31
32    // sodium_crypto_sign_publickey() で鍵ペアから公開鍵の部分を取り出します。
33    $publicKey = sodium_crypto_sign_publickey($originalKeypair);
34    echo "3. 抽出された公開鍵 (バイナリのHEX表現): " . bin2hex($publicKey) . PHP_EOL;
35
36    echo PHP_EOL;
37
38    // 3. 抽出した秘密鍵と公開鍵を使って、元の鍵ペアを再構築します。
39    // sodium_crypto_sign_keypair_from_secretkey_and_publickey() 関数は、
40    // 引数として秘密鍵と公開鍵を受け取り、それらを結合して完全な署名鍵ペアを生成します。
41    // これにより、秘密鍵と公開鍵を別々に保存していた場合でも、必要な時に元の完全な鍵ペアを再構成できます。
42    $reconstructedKeypair = sodium_crypto_sign_keypair_from_secretkey_and_publickey(
43        $secretKey,
44        $publicKey
45    );
46    echo "4. 再構築された鍵ペア (バイナリのHEX表現): " . bin2hex($reconstructedKeypair) . PHP_EOL;
47
48    echo PHP_EOL;
49
50    // 4. 再構築された鍵ペアが、最初に生成したオリジナルの鍵ペアと完全に一致するかを確認します。
51    if ($originalKeypair === $reconstructedKeypair) {
52        echo "✅ 成功: 再構築された鍵ペアは、最初に生成したオリジナルの鍵ペアと完全に一致します。" . PHP_EOL;
53        echo "このことは、関数が正しく秘密鍵と公開鍵を結合し、元の状態を復元できたことを意味します。" . PHP_EOL;
54    } else {
55        echo "❌ 失敗: 再構築された鍵ペアは、オリジナルの鍵ペアと一致しません。何らかのエラーが発生した可能性があります。" . PHP_EOL;
56    }
57
58    echo PHP_EOL . "--- デモ終了 ---" . PHP_EOL;
59}
60
61// 上記のデモンストレーション関数を実行します。
62demonstrateSodiumSignKeypairReconstruction();

sodium_crypto_sign_keypair_from_secretkey_and_publickey関数は、PHPのLibsodium拡張が提供する、デジタル署名に用いる鍵ペアを再構築するための重要な関数です。この関数は、既に独立して管理している秘密鍵と公開鍵の情報を結合し、署名生成や検証に必要な完全な鍵ペアとしてまとめ直す際に利用します。

具体的には、引数として秘密鍵を表す$secret_keyと公開鍵を表す$public_keyをそれぞれ文字列型(バイナリデータ)で受け取ります。そして、これら二つの鍵を正確に連結し、完全な署名鍵ペアを構築して文字列型(バイナリデータ)で返します。これにより、鍵ペア全体を保存するのではなく、秘密鍵と公開鍵を別々に保管し、必要に応じて本関数を使って元の鍵ペアを復元する運用が可能になります。

サンプルコードでは、まず新しい鍵ペアを生成し、そこから秘密鍵と公開鍵を抽出しています。その後、抽出したこれらの鍵を本関数に渡し、元の鍵ペアと寸分違わぬ形で再構築できることを実証しています。このプロセスは、分離された鍵データから完全な鍵ペアを安全かつ確実に復元できることを示しており、セキュリティを考慮した鍵管理戦略において非常に役立ちます。この関数を利用するには、PHP環境にLibsodium拡張が有効になっている必要があります。

Libsodium拡張がPHPにロードされていることを必ず確認してください。この関数は、既に生成され個別に保持されている秘密鍵と公開鍵の各バイナリデータを結合し、署名検証用の完全な鍵ペアとして再構成するために利用されます。鍵を新たに生成するものではありません。特に秘密鍵はセキュリティ上極めて重要であり、外部への漏洩や不適切な保管は致命的な脆弱性となります。本番環境では、鍵を環境変数や安全な鍵管理サービスなどを利用し、厳重に管理・運用することが必須です。今回の関数は署名鍵ペアを扱いますので、暗号化・復号化用のボックス鍵ペアと混同しないようご注意ください。

関連コンテンツ

関連IT用語

関連プログラミング言語