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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_sign_seed_keypair関数は、デジタル署名に使用する公開鍵と秘密鍵のペアを生成する関数です。この関数は、一般的な鍵生成とは異なり、与えられた「シード」(乱数の種)から決定論的に鍵ペアを生成します。つまり、同じシードを複数回入力として与えれば、常に全く同じ公開鍵と秘密鍵のペアが生成されるという特徴があります。

この機能は、特定の状況下で鍵の一貫性を保つ必要がある場合に非常に役立ちます。例えば、バックアップからシステムを復元する際に、過去に使用していたものと寸分違わない鍵ペアを再生成したい場合などに利用できます。

引数としては、SODIUM_CRYPTO_SIGN_SEEDBYTES定数で定義された長さのバイナリ文字列(シード)を一つ受け取ります。そして、戻り値として、生成された公開鍵と秘密鍵が連結されたバイナリ文字列を返します。

利用にあたっては、シードが外部に漏洩すると、誰でも同じ鍵ペアを生成できてしまうため、シードの厳重な管理と秘匿が極めて重要です。セキュリティを確保するため、シードは予測不能で十分に長い乱数から生成し、安全に保管してください。

構文(syntax)

1<?php
2$seed = random_bytes(SODIUM_CRYPTO_SIGN_SEEDBYTES);
3$keypair = sodium_crypto_sign_seed_keypair($seed);
4?>

引数(parameters)

string $seed

  • string $seed: 秘密鍵と公開鍵を生成するためのシードとなるバイト列を指定します。このシードは、暗号論的に安全な乱数生成器 (CSPRNG) によって生成される必要があります。

戻り値(return)

string

この関数は、指定されたシード(秘密の種)から生成された公開鍵と秘密鍵のペアを文字列として返します。

サンプルコード

PHP sodium_crypto_sign_seed_keypair で鍵ペア生成する

1<?php
2
3/**
4 * sodium_crypto_sign_seed_keypair 関数の使用例
5 *
6 * この関数は、指定されたシードから暗号署名用の秘密鍵と公開鍵のペアを生成します。
7 * システムエンジニアを目指す初心者向けに、LibSodium (PHPのsodium拡張) を用いた
8 * 鍵ペア生成の基本的な流れを示します。
9 */
10function generateSigningKeyPairFromSeedExample(): void
11{
12    // 1. sodium 拡張機能が有効か確認します。
13    // この拡張機能が有効でないと、sodium関連の関数は使用できません。
14    if (!extension_loaded('sodium')) {
15        echo "エラー: sodium 拡張機能が有効ではありません。\n";
16        echo "PHP の設定を確認し、'sodium' 拡張を有効にしてください。\n";
17        exit(1);
18    }
19
20    echo "--- sodium_crypto_sign_seed_keypair の使用例 ---\n\n";
21
22    // 2. 署名鍵ペア生成のための安全なシードを生成します。
23    // シードは、乱数ジェネレータによって生成される固定長のランダムな値です。
24    // SODIUM_CRYPTO_SIGN_SEEDBYTES は、必要なシードのバイト数 (通常32バイト) を定義する定数です。
25    try {
26        $seed = random_bytes(SODIUM_CRYPTO_SIGN_SEEDBYTES);
27    } catch (Exception $e) {
28        // random_bytes 関数が失敗した場合のエラーハンドリング
29        echo "エラー: シードの生成に失敗しました - " . $e->getMessage() . "\n";
30        exit(1);
31    }
32    
33    echo "生成されたシード (Hex): " . bin2hex($seed) . "\n\n";
34
35    // 3. sodium_crypto_sign_seed_keypair 関数を使って、シードから署名用の鍵ペアを生成します。
36    // 戻り値は、秘密鍵と公開鍵を結合した単一の文字列です。
37    $keypair = sodium_crypto_sign_seed_keypair($seed);
38
39    // 4. 生成された鍵ペアから秘密鍵と公開鍵を個別に抽出します。
40    // これらの関数は、結合された鍵ペアからそれぞれの鍵部分を安全に切り出します。
41    $secretKey = sodium_crypto_sign_secretkey($keypair);
42    $publicKey = sodium_crypto_sign_publickey($keypair);
43
44    echo "署名用の秘密鍵 (Hex): " . bin2hex($secretKey) . "\n";
45    echo "署名用の公開鍵 (Hex): " . bin2hex($publicKey) . "\n\n";
46
47    echo "補足:\n";
48    echo "・生成された秘密鍵は、メッセージにデジタル署名をするために使用されます。\n";
49    echo "・公開鍵は、その署名が秘密鍵で正しく作成されたものであるかを検証するために使用されます。\n";
50    echo "・秘密鍵は絶対に外部に漏洩させてはなりません。漏洩すると、誰でもあなたの身元を偽って署名を作成できてしまいます。\n";
51}
52
53// サンプル関数を実行します。
54generateSigningKeyPairFromSeedExample();
55
56?>

PHPのsodium_crypto_sign_seed_keypair関数は、デジタル署名に利用される秘密鍵と公開鍵のペアを、与えられたシード(種)から生成する重要な機能です。この関数は、PHPのsodium拡張を通じて、堅牢な暗号ライブラリLibSodiumの機能を提供します。

引数である$seedには、鍵ペアを生成するための基となるランダムなバイト列を渡します。このシードは予測不可能でなければならず、通常はrandom_bytes関数のような安全な乱数ジェネレータによって適切な長さで生成されます。異なるシードからは異なる鍵ペアが生成されます。

関数が返す戻り値は、生成された秘密鍵と公開鍵を結合した単一の文字列です。この結合された鍵ペアから、sodium_crypto_sign_secretkey関数を使用して秘密鍵を、またsodium_crypto_sign_publickey関数を使用して公開鍵をそれぞれ安全に抽出することができます。

生成された秘密鍵はメッセージにデジタル署名を行うために使用され、そのセキュリティ上、絶対に外部に漏洩させてはなりません。一方、公開鍵は、その署名が正しい秘密鍵で作成されたものであるかを検証するために使用され、共有しても問題ありません。秘密鍵の管理には細心の注意が必要です。

この関数を利用するには、まずPHPのsodium拡張機能が有効になっていることを確認してください。鍵ペア生成の元となるシードは、予測不可能な安全な乱数としてrandom_bytes関数などを用いて生成することが非常に重要です。固定値や予測可能なシードを使用すると、セキュリティが著しく低下します。

sodium_crypto_sign_seed_keypair関数が返す値は、秘密鍵と公開鍵を結合した単一の文字列です。これらを個別に利用する際は、sodium_crypto_sign_secretkeysodium_crypto_sign_publickey関数を使って正確に抽出してください。

生成された秘密鍵は、メッセージのデジタル署名に使用されるため、絶対に外部に漏洩させてはなりません。秘密鍵が漏洩すると、なりすましによる不正な署名が可能となり、深刻なセキュリティ問題を引き起こしますので、その管理には最大限の注意を払う必要があります。

PHP Libsodiumで署名キーペアを生成する

1<?php
2
3/**
4 * Libsodiumの署名機能を使って、シードから署名キーペアを生成し、
5 * メッセージの署名と検証を行うサンプルコードです。
6 *
7 * sodium_crypto_sign_seed_keypair は、与えられたシードから決定論的に
8 * 公開鍵と秘密鍵のペア(署名キーペア)を生成します。
9 * このキーペアはメッセージの認証と完全性の保証(署名)に使用されます。
10 *
11 * 注意: キーワードに「sodium_crypto_box」がありますが、
12 * sodium_crypto_box はメッセージの暗号化・復号化に使用される
13 * 別の種類のキーペア(ボックスキーペア)を扱います。
14 * ここで生成される署名キーペアは、sodium_crypto_box では直接使用できません。
15 */
16function demonstrateSodiumSignSeedKeypair(): void
17{
18    // 署名キーペア生成のためのシードを準備します。
19    // シードの長さは SODIUM_CRYPTO_SIGN_SEEDBYTES (32バイト) である必要があります。
20    // 本番環境では、安全な方法でシードを生成・管理してください。
21    $seed = random_bytes(SODIUM_CRYPTO_SIGN_SEEDBYTES);
22    echo "生成されたシード (HEX): " . bin2hex($seed) . PHP_EOL;
23
24    // シードから署名用の公開鍵と秘密鍵のペアを生成します。
25    $keypair = sodium_crypto_sign_seed_keypair($seed);
26    echo "署名キーペア生成成功。" . PHP_EOL;
27
28    // 生成されたキーペアから公開鍵と秘密鍵をそれぞれ抽出します。
29    $publicKey = sodium_crypto_sign_publickey($keypair);
30    $secretKey = sodium_crypto_sign_secretkey($keypair);
31
32    echo "公開鍵 (HEX): " . bin2hex($publicKey) . PHP_EOL;
33    // 秘密鍵は機密情報であり、決して公開したり漏洩させたりしてはいけません。
34    // デモンストレーションのため、ここでは表示を省略します。
35    // echo "秘密鍵 (HEX): " . bin2hex($secretKey) . PHP_EOL;
36
37    $originalMessage = "これは秘密鍵で署名される元のメッセージです。";
38    echo "元のメッセージ: " . $originalMessage . PHP_EOL;
39
40    // 秘密鍵を使ってメッセージに署名します。
41    // sodium_crypto_sign_detached は署名部分のみを返します。
42    $signature = sodium_crypto_sign_detached($originalMessage, $secretKey);
43    echo "生成された署名 (HEX): " . bin2hex($signature) . PHP_EOL;
44
45    // 公開鍵、署名、元のメッセージを使って署名を検証します。
46    // 署名が有効でメッセージが改ざんされていない場合、trueを返します。
47    if (sodium_crypto_sign_verify_detached($signature, $originalMessage, $publicKey)) {
48        echo "署名の検証に成功しました。メッセージは正しく、改ざんされていません。" . PHP_EOL;
49    } else {
50        echo "署名の検証に失敗しました。メッセージが改ざんされたか、署名が不正です。" . PHP_EOL;
51    }
52
53    echo PHP_EOL;
54
55    // 意図的にメッセージを改ざんした場合の検証例
56    $tamperedMessage = "これは改ざんされたメッセージです!";
57    echo "改ざんされたメッセージ: " . $tamperedMessage . PHP_EOL;
58
59    if (sodium_crypto_sign_verify_detached($signature, $tamperedMessage, $publicKey)) {
60        echo "誤って署名の検証に成功しました (これは起こるべきではありません)。" . PHP_EOL;
61    } else {
62        echo "改ざんされたメッセージでは署名の検証に失敗しました (期待される結果)。" . PHP_EOL;
63    }
64}
65
66// 関数を実行してデモンストレーションを開始します。
67demonstrateSodiumSignSeedKeypair();

PHPのsodium_crypto_sign_seed_keypair関数は、与えられたシード(種)から決定論的に署名用のキーペア(公開鍵と秘密鍵のペア)を生成します。このキーペアは、メッセージが正当な送信者によって送られ、かつ改ざんされていないことを保証するために使用されます。

引数$seedには、キーペア生成の元となる32バイトの文字列を渡します。同じシードを与えれば、常に同じキーペアが生成される点が特徴です。戻り値は、生成された公開鍵と秘密鍵が結合された形式の文字列です。このキーペアは、その後sodium_crypto_sign_publickey関数とsodium_crypto_sign_secretkey関数を用いて、それぞれ公開鍵と秘密鍵に分離して使用します。

サンプルコードでは、まず安全なシードを生成し、そのシードから署名キーペアを生成しています。次に、生成した秘密鍵でメッセージに署名を行い、その署名と元のメッセージ、公開鍵を使って検証に成功することを示しています。メッセージが改ざんされた場合は、検証が失敗する様子も確認できます。

キーワードにあるsodium_crypto_boxは、メッセージの暗号化と復号化に使うキーペアを扱う関数であり、署名キーペアとは異なる用途で利用されます。

sodium_crypto_sign_seed_keypairは、メッセージの署名と検証のためのキーペアを生成します。これはメッセージの暗号化に使用するsodium_crypto_boxとは目的が異なるため、混同しないよう注意が必要です。キーペアの元となるシードは、SODIUM_CRYPTO_SIGN_SEEDBYTESの長さで、安全に生成・管理することが極めて重要です。特に本番環境では、予測不能なシードを利用してください。また、生成される秘密鍵は機密情報であり、絶対に漏洩させてはいけません。このキーペアはメッセージの認証と完全性を保証しますが、メッセージの内容を暗号化する機能はありません。

関連コンテンツ

関連プログラミング言語