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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_sign_ed25519_sk_to_curve25519関数は、Ed25519署名方式で利用される秘密鍵を、Curve25519鍵交換方式で利用できる秘密鍵に変換する関数です。この関数は、PHPのSodium拡張機能によって提供され、暗号処理において異なる用途を持つ鍵の相互運用性を高める目的で使用されます。

具体的には、Ed25519はデジタル署名に特化した強力なアルゴリズムであり、メッセージの認証やデータの完全性保証に用いられます。一方、Curve25519は特にX25519(Diffie-Hellman鍵交換)プロトコルにおいて、共有秘密鍵の生成や鍵交換に広く利用されます。この二つのアルゴリズムは同じ楕円曲線(Curve25519)を基盤としているため、技術的に秘密鍵を相互に変換することが可能です。

この関数を使用することで、既存のEd25519形式の秘密鍵を、Curve25519形式に変換し、X25519などの鍵交換プロトコルにそのまま適用できるようになります。これにより、鍵ペアの管理を簡素化し、一つの秘密鍵から署名と鍵交換の両方の用途に対応できる柔軟なシステムを構築することが可能になります。例えば、Ed25519でアイデンティティを証明したエンティティが、その秘密鍵から導出されたCurve25519秘密鍵を用いて安全な通信路を確立するといったシナリオで有効です。この変換された秘密鍵も、元の秘密鍵と同様に厳重に保護する必要があることに留意してください。

構文(syntax)

1<?php
2
3$keypair = sodium_crypto_sign_keypair();
4$ed25519_secret_key = sodium_crypto_sign_secretkey($keypair);
5
6$curve25519_secret_key = sodium_crypto_sign_ed25519_sk_to_curve25519($ed25519_secret_key);
7
8// $curve25519_secret_key は Curve25519 の秘密鍵 (32バイト)
9// このキーは sodium_crypto_box_keypair_from_secretkey で Curve25519 のキーペアを生成するのに使える
10
11?>

引数(parameters)

string $secret_key

  • string $secret_key: Ed25519署名秘密鍵のバイナリ文字列

戻り値(return)

string

sodium_crypto_sign_ed25519_sk_to_curve25519 関数は、Ed25519 秘密鍵を Curve25519 秘密鍵に変換した結果を文字列として返します。

サンプルコード

Ed25519鍵をCurve25519鍵へ変換しsodium_crypto_boxで暗号化する

1<?php
2
3// このファイルは単体で実行可能です。
4// PHPのSodium拡張が有効になっていることを確認してください。
5
6/**
7 * Ed25519署名鍵ペアをCurve25519ボックス鍵ペアに変換し、
8 * sodium_crypto_box を用いたメッセージの暗号化・復号化の例を示します。
9 *
10 * システムエンジニアを目指す初心者の方へ:
11 * このコードは、デジタル署名に使われるEd25519鍵ペアを、
12 * メッセージの暗号化に使われるCurve25519鍵ペアに変換し、
13 * 実際にメッセージを安全にやり取りする基本的な流れを示しています。
14 *
15 * - Ed25519: 主にデジタル署名に使われるアルゴリズム。
16 * - Curve25519: 主に鍵交換やメッセージ暗号化に使われるアルゴリズム。
17 * - sodium_crypto_box: Curve25519を利用した強力な非対称暗号(ボックス暗号)機能。
18 * - シークレットキー (秘密鍵): 誰にも見せてはいけない鍵。メッセージの復号や署名に使う。
19 * - パブリックキー (公開鍵): 誰にでも公開できる鍵。メッセージの暗号化や署名の検証に使う。
20 * - ノンス (Nonce): 一度だけ使用するランダムな値。同じ鍵で複数回暗号化する際に必須で、メッセージの再送攻撃を防ぎます。
21 */
22function demonstrate_crypto_box_with_ed25519_conversion(): void
23{
24    echo "--- Ed25519からCurve25519への鍵変換とsodium_crypto_boxのデモンストレーション ---" . PHP_EOL;
25
26    // 1. アリスのEd25519署名鍵ペアを生成
27    // この鍵ペアは、通常は署名目的で使用されます。
28    $alice_sign_keypair = sodium_crypto_sign_keypair();
29    $alice_sign_secret_key = sodium_crypto_sign_secretkey($alice_sign_keypair);
30    $alice_sign_public_key = sodium_crypto_sign_publickey($alice_sign_keypair);
31    echo "1. アリスのEd25519署名鍵ペアを生成しました。" . PHP_EOL;
32
33    // 2. Ed25519署名秘密鍵からCurve25519ボックス秘密鍵へ変換
34    // sodium_crypto_box_open (復号) のためにアリスのCurve25519秘密鍵が必要です。
35    // sodium_crypto_sign_ed25519_sk_to_curve25519 関数を使用します。
36    $alice_curve25519_secret_key = sodium_crypto_sign_ed25519_sk_to_curve25519($alice_sign_secret_key);
37    // Ed25519署名公開鍵からCurve25519ボックス公開鍵へ変換
38    // sodium_crypto_box (暗号化) のためにアリスのCurve25519公開鍵が必要です。
39    $alice_curve25519_public_key = sodium_crypto_sign_ed25519_pk_to_curve25519($alice_sign_public_key);
40    echo "2. アリスのEd25519鍵をCurve25519鍵に変換しました。" . PHP_EOL;
41
42    // 3. ボブのEd25519署名鍵ペアを生成
43    // アリスと同様にボブも鍵ペアを持ちます。
44    $bob_sign_keypair = sodium_crypto_sign_keypair();
45    $bob_sign_secret_key = sodium_crypto_sign_secretkey($bob_sign_keypair);
46    $bob_sign_public_key = sodium_crypto_sign_publickey($bob_sign_keypair);
47    echo "3. ボブのEd25519署名鍵ペアを生成しました。" . PHP_EOL;
48
49    // 4. ボブのEd25519鍵をCurve25519鍵へ変換
50    // sodium_crypto_box (暗号化) のためにボブのCurve25519公開鍵が必要です。
51    // sodium_crypto_box_open (復号) のためにボブのCurve25519秘密鍵が必要です。
52    $bob_curve25519_secret_key = sodium_crypto_sign_ed25519_sk_to_curve25519($bob_sign_secret_key);
53    $bob_curve25519_public_key = sodium_crypto_sign_ed25519_pk_to_curve25519($bob_sign_public_key);
54    echo "4. ボブのEd25519鍵をCurve25519鍵に変換しました。" . PHP_EOL;
55
56    // 5. アリスがボブ宛にメッセージを暗号化
57    $message = "こんにちは、ボブ。これはアリスからの秘密のメッセージです!";
58    echo PHP_EOL . "元のメッセージ: " . $message . PHP_EOL;
59
60    // 暗号化に使用するノンス(Nonce)を生成します。
61    // ノンスは毎回異なる値を使用する必要があります。同じ鍵で異なるメッセージを暗号化する場合でも必須です。
62    $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
63
64    // sodium_crypto_box を使用してメッセージを暗号化します。
65    // 引数: メッセージ, ノンス, 受信者の公開鍵 + 送信者の秘密鍵
66    // ここでは、アリスが送信者、ボブが受信者なので、
67    // ボブのCurve25519公開鍵 と アリスのCurve25519秘密鍵 を結合して使用します。
68    $ciphertext = sodium_crypto_box(
69        $message,
70        $nonce,
71        $bob_curve25519_public_key . $alice_curve25519_secret_key
72    );
73    echo "5. アリスがメッセージを暗号化しました。暗号文 (Base64エンコード): " . base64_encode($ciphertext) . PHP_EOL;
74
75    // 6. ボブがアリスからの暗号化されたメッセージを復号
76    // sodium_crypto_box_open を使用してメッセージを復号します。
77    // 引数: 暗号文, ノンス, 送信者の公開鍵 + 受信者の秘密鍵
78    // ここでは、アリスが送信者、ボブが受信者なので、
79    // アリスのCurve25519公開鍵 と ボブのCurve25519秘密鍵 を結合して使用します。
80    $decrypted_message = sodium_crypto_box_open(
81        $ciphertext,
82        $nonce,
83        $alice_curve25519_public_key . $bob_curve25519_secret_key
84    );
85
86    if ($decrypted_message === false) {
87        echo "エラー: メッセージの復号に失敗しました。" . PHP_EOL;
88        return;
89    }
90
91    echo "6. ボブがメッセージを復号しました。復号されたメッセージ: " . $decrypted_message . PHP_EOL;
92
93    // 7. 元のメッセージと復号されたメッセージが一致するか確認
94    if ($message === $decrypted_message) {
95        echo PHP_EOL . "結果: メッセージは正常に暗号化および復号されました。" . PHP_EOL;
96    } else {
97        echo PHP_EOL . "結果: エラーが発生しました。元のメッセージと復号されたメッセージが一致しません。" . PHP_EOL;
98    }
99}
100
101// スクリプトを実行
102demonstrate_crypto_box_with_ed25519_conversion();
103
104?>

sodium_crypto_sign_ed25519_sk_to_curve25519関数は、PHP 8のSodium拡張で提供される暗号機能の一つです。この関数は、Ed25519アルゴリズムによって生成されたデジタル署名用の秘密鍵を、Curve25519アルゴリズムで利用できるメッセージ暗号化用の秘密鍵に変換する目的で使用されます。Ed25519は主にデジタル署名に、Curve25519は主に鍵交換やメッセージの暗号化に特化しているため、異なる用途で鍵を共有したい場合にこの変換が役立ちます。

引数 $secret_keyには、Ed25519署名スキームで生成された秘密鍵を文字列として渡します。この関数は、そのEd25519秘密鍵に対応するCurve25519秘密鍵を文字列として返します。

サンプルコードでは、まずアリスとボブがEd25519の署名鍵ペアをそれぞれ生成します。次に、sodium_crypto_sign_ed25519_sk_to_curve25519関数を用いて、各々のEd25519秘密鍵をCurve25519秘密鍵へ変換しています。さらに公開鍵も対応するCurve25519公開鍵に変換することで、メッセージの暗号化・復号に必要なCurve25519の鍵ペアを準備します。その後、アリスは変換したボブのCurve25519公開鍵と自身のCurve25519秘密鍵を組み合わせてsodium_crypto_box関数でメッセージを暗号化します。ボブは、アリスのCurve25519公開鍵と自身のCurve25519秘密鍵を組み合わせてsodium_crypto_box_open関数でメッセージを復号し、安全な通信が成立する様子が示されています。これにより、一つのEd25519鍵ペアから署名と暗号化の両方に利用できる鍵ペアを効率的に派生させることが可能になります。

このコードを利用する上で、まずノンスは暗号化ごとに必ず異なるランダムな値を生成し、使い回さないでください。同じノンスを複数回使用すると、メッセージの再送攻撃など深刻なセキュリティリスクにつながります。次に、変換後の秘密鍵も元の秘密鍵と同様に誰にも知られないよう厳重に管理することが不可欠です。漏洩するとメッセージの機密性が完全に失われます。また、sodium_crypto_boxsodium_crypto_box_openで鍵を結合する際には、公開鍵と秘密鍵の結合順序がそれぞれ異なるため、サンプルコードの指定方法をよく理解し、正確に適用してください。この機能を利用するには、PHPのSodium拡張が有効になっている必要があります。

Ed25519秘密鍵をCurve25519に変換する

1<?php
2
3/**
4 * Ed25519 署名秘密鍵を Curve25519 鍵共有秘密鍵に変換する例を示します。
5 *
6 * この関数は、デジタル署名に使用される Ed25519 鍵ペアを生成し、
7 * その秘密鍵を鍵共有プロトコル(Diffie-Hellmanなど)で使用される
8 * Curve25519 形式の秘密鍵に変換するプロセスを実演します。
9 *
10 * sodium_crypto_sign_keypair() で Ed25519 鍵ペアを生成し、
11 * sodium_crypto_sign_secretkey() でその秘密鍵を抽出し、
12 * 最終的に sodium_crypto_sign_ed25519_sk_to_curve25519() で変換します。
13 */
14function demonstrateKeyConversion(): void
15{
16    // 1. Ed25519 署名鍵ペアを生成します。
17    // この鍵ペアは、メッセージのデジタル署名に使用されます。
18    // 戻り値は公開鍵と秘密鍵を結合した文字列です。
19    $ed25519Keypair = sodium_crypto_sign_keypair();
20
21    // 2. 生成された鍵ペアから Ed25519 秘密鍵を抽出します。
22    // この秘密鍵を使ってメッセージに署名することができます。
23    $ed25519SecretKey = sodium_crypto_sign_secretkey($ed25519Keypair);
24
25    echo "--- Ed25519 Key Pair Generation and Conversion Example ---\n\n";
26    echo "Generated Ed25519 Secret Key (hex): " . bin2hex($ed25519SecretKey) . "\n";
27    echo "Generated Ed25519 Public Key (hex): " . bin2hex(sodium_crypto_sign_publickey($ed25519Keypair)) . "\n\n";
28
29    // 3. Ed25519 の秘密鍵を Curve25519 の秘密鍵に変換します。
30    // Curve25519 は主に Diffie-Hellman 鍵共有プロトコルで使用される楕円曲線です。
31    // この変換により、Ed25519 の署名目的で生成された秘密鍵を、
32    // 鍵共有の目的で再利用できるようになります。
33    $curve25519SecretKey = sodium_crypto_sign_ed25519_sk_to_curve25519($ed25519SecretKey);
34
35    echo "Converted Curve25519 Secret Key (hex): " . bin2hex($curve25519SecretKey) . "\n\n";
36
37    // 注意: 秘密鍵は非常に機密性の高い情報です。
38    // 実際のアプリケーションでは、決して直接出力したり、
39    // 安全でない方法で保存または送信したりしないでください。
40}
41
42// サンプル関数を実行して、変換プロセスを確認します。
43demonstrateKeyConversion();
44
45?>

PHPのsodium_crypto_sign_ed25519_sk_to_curve25519関数は、Ed25519形式のデジタル署名秘密鍵を、Curve25519形式の鍵共有秘密鍵に変換するために使用されます。Ed25519はメッセージのデジタル署名に適しており、Curve25519はDiffie-Hellmanなどの鍵共有プロトコルで主に利用される楕円曲線暗号です。この関数は、引数として指定されたEd25519の秘密鍵(string $secret_key)を受け取り、対応するCurve25519の秘密鍵を文字列(string)として返します。

サンプルコードでは、まずsodium_crypto_sign_keypair()関数でEd25519の署名鍵ペアを生成し、sodium_crypto_sign_secretkey()関数でその鍵ペアからEd25519秘密鍵を抽出しています。その後、抽出したEd25519秘密鍵をsodium_crypto_sign_ed25519_sk_to_curve25519()に渡すことで、Curve25519形式の秘密鍵へ変換しています。この変換は、デジタル署名用に生成された秘密鍵を、鍵共有の目的でも安全に再利用できるようにすることを可能にします。これにより、異なる暗号化プロトコル間で同じ秘密情報を活用する柔軟性が生まれます。秘密鍵は非常に機密性の高い情報ですので、実際のシステムでは厳重な取り扱いが必要です。

このサンプルコードは、Ed25519署名秘密鍵をCurve25519鍵共有秘密鍵に変換する手順を示しています。システムエンジニアを目指す初心者の方は、特に秘密鍵の取り扱いに十分注意してください。生成・変換された秘密鍵は極めて機密性が高く、本番環境では決して画面に出力したり、安全でない方法で保存・送信したりしてはいけません。また、この機能を使用するにはPHPのsodium拡張が有効になっている必要がありますので、事前にサーバー環境をご確認ください。Ed25519はデジタル署名、Curve25519は鍵共有に適したアルゴリズムであり、この変換は異なるセキュリティ目的で鍵を再利用する技術であることを理解することが重要です。暗号関連の機能を扱う際は、常にセキュリティのベストプラクティスに従うよう心がけてください。

関連コンテンツ

関連IT用語

関連プログラミング言語