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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_sign_keypair関数は、デジタル署名に利用する公開鍵と秘密鍵のペアを生成する関数です。デジタル署名は、データが改ざんされていないこと、および送信者が確かに本人であることを証明するための暗号技術です。この関数は、暗号学的に安全な乱数を用いて、一意な秘密鍵と公開鍵を生成します。

生成される秘密鍵は、メッセージに署名を行うために使用され、その所有者だけが知っているべき非常に重要な情報です。秘密鍵が漏洩すると、なりすましや偽の署名が作成されるなど、深刻なセキュリティリスクにつながるため、厳重に管理する必要があります。一方、公開鍵は、署名されたメッセージの正当性を検証するために使用されます。公開鍵は安全に公開することができ、署名を受け取った誰もがその鍵を使って署名が有効であるかを確認できます。

この関数は、生成された秘密鍵と公開鍵を組み合わせた鍵ペアをバイナリ文字列として返します。この鍵ペアは、PHPのSodium拡張機能の他の関数(例えば、sodium_crypto_signで署名を作成したり、sodium_crypto_sign_openで署名を検証したりする際)で利用されます。セキュアな通信やデータの完全性を保証するシステムを構築する上で、この鍵ペアの安全な生成は不可欠な最初のステップとなります。

構文(syntax)

1<?php
2
3$keypair = sodium_crypto_sign_keypair();
4
5?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

string

この関数は、公開鍵と秘密鍵のペアを生成し、それらを連結したバイナリ文字列を返します。

サンプルコード

PHPで署名鍵ペアを生成する

1<?php
2
3/**
4 * sodium_crypto_sign_keypair 関数を使用して、新しい署名鍵ペアを生成するサンプルコードです。
5 *
6 * この関数は、libsodium拡張機能がインストールされているPHP環境でのみ動作します。
7 * (例: php.iniで 'extension=sodium' のコメント解除、または `sudo apt install php-sodium` など)
8 *
9 * システムエンジニアを目指す初心者の方へ:
10 * 鍵ペアとは、特定の暗号操作(この場合はデジタル署名)を行うための2つの関連する鍵のことです。
11 * - 公開鍵: 誰にでも公開できる鍵で、データの検証に使用されます。
12 * - 秘密鍵: 決して他人に知られてはならない鍵で、データの署名に使用されます。
13 * sodium_crypto_sign_keypair は、これら2つの鍵を安全に生成します。
14 */
15function generateSodiumSignKeypairExample(): void
16{
17    echo "--- libsodium 署名鍵ペア生成 --- \n\n";
18
19    // sodium_crypto_sign_keypair() を呼び出して、新しい鍵ペアを生成します。
20    // この関数は引数を取りません。
21    // 戻り値は、秘密鍵と公開鍵が連結されたバイナリ文字列です。
22    $keypair = sodium_crypto_sign_keypair();
23
24    // 鍵ペアが正常に生成されたかを確認します。
25    if ($keypair === false) {
26        echo "エラー: 鍵ペアの生成に失敗しました。libsodium拡張機能が有効になっているか確認してください。\n";
27        return;
28    }
29
30    echo "鍵ペアが正常に生成されました。\n\n";
31
32    // 鍵ペアから秘密鍵を抽出します。
33    // 秘密鍵はデータを署名するために使われます。これは絶対に秘密にしてください。
34    $secretKey = sodium_crypto_sign_secretkey($keypair);
35    echo "秘密鍵 (バイナリを16進数に変換): " . bin2hex($secretKey) . "\n";
36    echo "秘密鍵の長さ: " . strlen($secretKey) . " バイト\n\n";
37
38    // 鍵ペアから公開鍵を抽出します。
39    // 公開鍵は署名が正しいか検証するために使われます。これは共有しても安全です。
40    $publicKey = sodium_crypto_sign_publickey($keypair);
41    echo "公開鍵 (バイナリを16進数に変換): " . bin2hex($publicKey) . "\n";
42    echo "公開鍵の長さ: " . strlen($publicKey) . " バイト\n\n";
43
44    echo "補足:\n";
45    echo "- 鍵は通常バイナリデータとして扱われます。表示のために bin2hex() で16進数文字列に変換しています。\n";
46    echo "- 秘密鍵は厳重に管理し、決して公開しないでください。\n";
47    echo "- 公開鍵は安心して共有でき、署名の検証に使用されます。\n";
48}
49
50// 関数を実行して、鍵ペア生成処理を開始します。
51generateSodiumSignKeypairExample();
52
53?>

PHP 8のsodium_crypto_sign_keypair関数は、libsodium拡張機能を用いてデジタル署名用の新しい鍵ペアを安全に生成します。この関数は引数を持たず、秘密鍵と公開鍵が連結されたバイナリ文字列を戻り値として返します。この戻り値から、後続の関数で秘密鍵と公開鍵をそれぞれ抽出して利用します。

鍵ペアは「公開鍵」と「秘密鍵」で構成されます。公開鍵は署名の検証に使い誰にでも共有できますが、秘密鍵は署名生成に使い、決して他人に公開してはいけません。

サンプルコードでは、sodium_crypto_sign_keypair()で鍵ペアを生成後、sodium_crypto_sign_secretkey()sodium_crypto_sign_publickey()で各鍵を抽出します。鍵はバイナリデータですが、表示のためbin2hex()で16進数に変換しています。この関数はlibsodium拡張機能が有効なPHP環境でのみ動作し、秘密鍵の厳重な管理はセキュリティ上非常に重要です。

この関数はPHPのlibsodium拡張機能が有効な環境でのみ動作するため、導入と設定が必要です。処理が失敗した場合はfalseを返すので、戻り値を確認しエラー処理を行ってください。生成される鍵ペアは秘密鍵と公開鍵が結合されたバイナリ文字列であり、sodium_crypto_sign_secretkeysodium_crypto_sign_publickeyといった関数で各鍵を分離して利用します。特に秘密鍵はデータを署名するために用いられ、決して外部に漏らさないよう厳重な管理が求められます。一方、公開鍵は署名の検証に使用されるため安全に共有できます。鍵はバイナリデータとして扱われるため、表示する際はbin2hex()などで16進数に変換すると便利です。

PHP sodium_crypto_sign_keypairで署名鍵ペア生成

1<?php
2
3/**
4 * Libsodiumの署名鍵ペア生成と署名・検証のサンプル
5 *
6 * sodium_crypto_sign_keypair は、メッセージのデジタル署名に使用する公開鍵と秘密鍵のペアを生成します。
7 * このサンプルは、鍵ペアの生成からメッセージの署名、そしてその署名の検証までの一連の流れを示し、
8 * メッセージの認証と完全性を保証する方法を実演します。
9 */
10function generateAndVerifyDigitalSignatureExample(): void
11{
12    // 1. 署名鍵ペアを生成
13    // sodium_crypto_sign_keypair は、メッセージの署名と検証に必要な秘密鍵と公開鍵のペアを生成します。
14    // 戻り値は、秘密鍵と公開鍵が連結されたバイナリ文字列です。
15    $keyPair = sodium_crypto_sign_keypair();
16    echo "--- 鍵ペア生成 ---\n";
17    echo "署名鍵ペアが生成されました (バイナリ長: " . strlen($keyPair) . " バイト)\n\n";
18
19    // 2. 鍵ペアから秘密鍵と公開鍵を抽出
20    // sodium_crypto_sign_secretkey 関数は、生成された鍵ペアから秘密鍵を抽出します。
21    $secretKey = sodium_crypto_sign_secretkey($keyPair);
22    // sodium_crypto_sign_publickey 関数は、生成された鍵ペアから公開鍵を抽出します。
23    $publicKey = sodium_crypto_sign_publickey($keyPair);
24
25    echo "秘密鍵 (バイナリ長: " . strlen($secretKey) . " バイト)\n";
26    echo "公開鍵 (バイナリ長: " . strlen($publicKey) . " バイト)\n\n";
27
28    // 3. 署名するメッセージを定義
29    $message = 'この機密メッセージは、デジタル署名によって保護されています。';
30    echo "--- 署名プロセス ---\n";
31    echo "元のメッセージ: " . $message . "\n\n";
32
33    // 4. 秘密鍵を使ってメッセージに署名
34    // sodium_crypto_sign 関数は、指定されたメッセージにデジタル署名を付与します。
35    // 戻り値は、署名と元のメッセージが連結されたバイナリ文字列です。
36    $signedMessage = sodium_crypto_sign($message, $secretKey);
37    echo "メッセージに署名が付けられました (バイナリ長: " . strlen($signedMessage) . " バイト)\n\n";
38
39    // 5. 公開鍵を使って署名を検証し、元のメッセージを取り出す
40    // sodium_crypto_sign_open 関数は、署名を検証し、有効であれば元のメッセージを返します。
41    // 署名が無効な場合やメッセージが改ざんされている場合は false を返します。
42    echo "--- 検証プロセス ---\n";
43    $verifiedMessage = sodium_crypto_sign_open($signedMessage, $publicKey);
44
45    if ($verifiedMessage !== false) {
46        echo "✅ 署名検証成功!メッセージは認証され、改ざんされていません。\n";
47        echo "検証されたメッセージ: " . $verifiedMessage . "\n";
48    } else {
49        echo "❌ 署名検証失敗。メッセージが改ざんされたか、署名が無効です。\n";
50    }
51
52    // --- 意図的な改ざんの検証例 ---
53    echo "\n--- 意図的な改ざんの検証例 ---\n";
54    // 署名済みメッセージの一部を意図的に改ざんしてみます。
55    // 署名部分のバイト長を考慮して、メッセージ部分を改ざんします。
56    $tamperedSignedMessage = $signedMessage;
57    $messageOffset = sodium_crypto_sign_BYTES; // 署名部分のバイト長 (64バイト)
58
59    if (strlen($tamperedSignedMessage) > $messageOffset) {
60        // メッセージの最初の1バイトを反転させて改ざん
61        $tamperedSignedMessage[$messageOffset] = chr(ord($tamperedSignedMessage[$messageOffset]) ^ 0xFF);
62    } else {
63        echo "注: メッセージが短すぎて改ざんできませんでした。\n";
64    }
65
66    $tamperedVerifiedMessage = sodium_crypto_sign_open($tamperedSignedMessage, $publicKey);
67
68    if ($tamperedVerifiedMessage !== false) {
69        echo "❌ 警告: 不正な署名にもかかわらず検証成功?! (これは予期せぬ動作です)\n";
70    } else {
71        echo "✅ 不正な署名または改ざんされたメッセージのため検証失敗。期待通りの動作です。\n";
72    }
73}
74
75// サンプル関数の実行
76generateAndVerifyDigitalSignatureExample();

PHP 8のsodium_crypto_sign_keypair関数は、メッセージのデジタル署名に使用する公開鍵と秘密鍵のペアを生成します。この関数は引数を取らず、戻り値として秘密鍵と公開鍵が連結されたバイナリ文字列を返します。デジタル署名は、メッセージが特定の送信者によって作成され、送信中に内容が改ざんされていないことを保証するために利用される重要なセキュリティ技術です。

このサンプルコードは、sodium_crypto_sign_keypairによって生成された鍵ペアを用いて、メッセージに署名し、その署名を検証する一連のプロセスを示しています。まず、鍵ペアを生成した後、そこから秘密鍵と公開鍵をそれぞれ抽出します。次に、秘密鍵を使用してメッセージにデジタル署名を付与します。この署名されたメッセージは、対応する公開鍵を使って検証することができ、メッセージの認証と完全性が確認されます。検証が成功すれば、メッセージは正規のものであり、改ざんされていないと判断できます。さらに、メッセージが意図的に改ざんされた場合に、署名検証が失敗する例も示されており、デジタル署名がどのようにメッセージの完全性を保護しているかを具体的に理解することができます。

生成された秘密鍵は極めて機密性が高いため、厳重に保管し、決して外部に漏洩させないでください。漏洩すると第三者によるメッセージの偽装が可能となります。sodium_crypto_sign_keypairなどが返す値はバイナリ文字列ですので、画面に表示したりファイルに保存する際は、Base64エンコードなど適切な形式に変換すると安全かつ確実です。この機能はメッセージの認証と完全性を保証するデジタル署名であり、キーワードにあるsodium_crypto_boxが提供するメッセージの機密性(暗号化)とは目的が異なります。混同せず、用途に応じて適切に使い分けてください。署名検証の結果(sodium_crypto_sign_openの戻り値)を必ず確認し、falseの場合はメッセージが改ざんされている、または署名が無効であると判断してください。

関連コンテンツ

関連プログラミング言語