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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_box_seal_open関数は、匿名で暗号化されたメッセージを復号化する関数です。この関数は、PHPのSodium拡張機能の一部として提供されており、送信者の身元を隠しながら、特定の受信者のみがメッセージを読めるようにする「シーリング」と呼ばれる暗号化方式で作成されたデータを処理します。

具体的には、sodium_crypto_box_seal関数によって暗号化されたメッセージを受け取り、受信者自身の秘密鍵と公開鍵のペアを使用して、そのメッセージを元の平文に戻す役割を担います。この方式の大きな特徴は、メッセージを暗号化した送信者が誰であるかを、受信者側が知ることができない匿名性にあります。

この関数を使用する際は、暗号化されたメッセージ本体($ciphertext)、受信者自身の秘密鍵($secret_key)、そして受信者自身の公開鍵($public_key)の3つの情報を提供する必要があります。これらの鍵情報と暗号文が正しく一致した場合にのみ、安全にメッセージが復号されます。復号に成功すると、元のメッセージが文字列として返されますが、鍵が不一致であったり、暗号文が改ざんされているなどの理由で復号に失敗した場合はfalseが返されます。

この機能は、メッセージの内容を第三者から保護しつつ、送信者の身元を匿名に保ちたい、といったプライバシーを重視した通信シナリオで活用されます。セキュリティを必要とするアプリケーション開発において、データ秘匿と匿名性を両立させる重要な手段の一つです。

構文(syntax)

1<?php
2
3$message = sodium_crypto_box_seal_open(
4    $ciphertext,
5    $recipient_public_key,
6    $recipient_secret_key
7);

引数(parameters)

string $ciphertext, string $key_pair

  • string $ciphertext: 復号化する暗号化されたデータ(シール)
  • string $key_pair: 復号化に使用する秘密鍵(公開鍵暗号化ペアの秘密鍵部分)

戻り値(return)

string|false

暗号化されたメッセージを復号し、元の文字列を返します。復号に失敗した場合は false を返します。

サンプルコード

sodium_crypto_box_seal_openで匿名暗号化を復号する

1<?php
2
3/**
4 * PHP Sodium拡張のsodium_crypto_box_seal_open関数の使用例。
5 * この関数は、匿名で暗号化されたメッセージを復号するために使用されます。
6 *
7 * sodium_crypto_box_seal_openは、sodium_crypto_box_sealによって暗号化されたメッセージを
8 * 受信者の秘密鍵と公開鍵のペア($key_pair)を用いて復号します。
9 *
10 * @return void
11 */
12function demonstrateSodiumCryptoBoxSealOpen(): void
13{
14    // 1. PHP Sodium拡張が有効になっているかを確認します。
15    if (!extension_loaded('sodium')) {
16        echo "エラー: Sodium拡張が有効になっていません。\n";
17        echo "PHPの設定を確認し、extension=sodium.so (または extension=sodium.dll) が有効になっていることを確認してください。\n";
18        return;
19    }
20
21    // 2. 受信者の鍵ペアを生成します。
22    //    この鍵ペアには、受信者の秘密鍵と公開鍵の両方が含まれます。
23    //    sodium_crypto_box_seal_openで復号するために必要です。
24    $receiverKeyPair = sodium_crypto_box_keypair();
25    echo "受信者の鍵ペアを生成しました。\n";
26
27    // 3. 受信者の公開鍵を抽出します。
28    //    この公開鍵は、メッセージを暗号化する側(送信者)がメッセージを暗号化する際に使用します。
29    $receiverPublicKey = sodium_crypto_box_publickey($receiverKeyPair);
30    echo "受信者の公開鍵を抽出しました。\n";
31
32    // 4. 暗号化する元のメッセージ(プレーンテキスト)を準備します。
33    $originalMessage = "これは匿名で安全に送られる秘密のメッセージです。";
34    echo "元のメッセージ: \"" . $originalMessage . "\"\n";
35
36    // 5. メッセージを暗号化します (sodium_crypto_box_sealを使用)。
37    //    sodium_crypto_box_sealは、受信者の公開鍵のみを使用してメッセージを暗号化します。
38    //    送信者の鍵は必要なく、送信者の身元を明かすことなく暗号化できます(匿名暗号化)。
39    $sealedCiphertext = sodium_crypto_box_seal($originalMessage, $receiverPublicKey);
40    echo "メッセージを匿名で暗号化しました。\n";
41    // 暗号化されたデータはバイナリなので、表示のためにBase64エンコードします。
42    echo "暗号化されたメッセージ (Base64エンコード): " . base64_encode($sealedCiphertext) . "\n\n";
43
44    // 6. 暗号化されたメッセージを復号します (sodium_crypto_box_seal_openを使用)。
45    //    復号するには、暗号化されたメッセージ($sealedCiphertext)と、
46    //    受信者自身の鍵ペア($receiverKeyPair)が必要です。
47    $decryptedMessage = sodium_crypto_box_seal_open($sealedCiphertext, $receiverKeyPair);
48
49    // 7. 復号の結果を確認し、出力します。
50    if ($decryptedMessage === false) {
51        echo "エラー: メッセージの復号に失敗しました。鍵ペアが間違っているか、メッセージが破損している可能性があります。\n";
52    } else {
53        echo "メッセージの復号に成功しました。\n";
54        echo "復号されたメッセージ: \"" . $decryptedMessage . "\"\n";
55
56        // 元のメッセージと復号されたメッセージが一致するかを確認します。
57        if ($originalMessage === $decryptedMessage) {
58            echo "元のメッセージと復号されたメッセージは一致します。暗号化と復号が正しく行われました。\n";
59        } else {
60            echo "警告: 元のメッセージと復号されたメッセージが一致しませんでした。\n";
61        }
62    }
63}
64
65// サンプル関数を実行します。
66demonstrateSodiumCryptoBoxSealOpen();
67
68?>

PHP 8のsodium_crypto_box_seal_open関数は、匿名で暗号化されたメッセージを安全に復号するために利用されます。この関数は、sodium_crypto_box_seal関数によって、メッセージ送信者が自身の身元を明かすことなく、受信者の公開鍵のみを用いて暗号化したデータを、元の状態に戻す役割を果たします。

具体的な使用方法として、第一引数$ciphertextには、復号したいバイナリ形式の暗号化済みメッセージを指定します。第二引数$key_pairには、メッセージを受信する側のユーザーが持つ、秘密鍵と公開鍵がセットになった「鍵ペア」を渡します。この鍵ペアは、sodium_crypto_box_keypair()関数で生成されるものです。

復号処理が成功すると、暗号化される前の元のメッセージが文字列として返されます。しかし、指定された鍵ペアが暗号化時と異なる場合や、暗号化されたメッセージが途中で改ざん・破損している場合など、復号に失敗した際には戻り値としてfalseが返されます。この戻り値を確認することで、処理の成否を判断することができます。sodium_crypto_box_seal_openは、セキュアな匿名通信を実現する上で重要な機能を提供します。

この関数を利用する際は、PHPのSodium拡張が必ず有効になっていることを確認してください。引数$key_pairには、メッセージの復号を行う受信者自身の鍵ペア(秘密鍵と公開鍵の両方を含む)を指定する必要があります。メッセージの暗号化に用いられた送信者の鍵や、受信者の公開鍵単独では復号できませんのでご注意ください。関数が失敗した場合はfalseが返されるため、必ず戻り値を確認し、復号失敗時の適切なエラー処理を実装することが重要です。この関数はsodium_crypto_box_sealで匿名暗号化されたメッセージの復号に特化しており、それ以外の方法で暗号化されたデータには使用できません。

Sodiumで匿名公開鍵暗号化を実装する

1<?php
2
3/**
4 * PHPのsodium_crypto_box_seal_open関数を使用して、
5 * 匿名公開鍵暗号化/復号のデモンストレーションを行います。
6 *
7 * この関数は、システムエンジニアを目指す初心者向けに、
8 * libsodium拡張の基本的な使い方を正確かつ簡潔に示します。
9 *
10 * sodium_crypto_box_seal_open は、事前に共有された秘密鍵なしで
11 * メッセージを暗号化し、指定された鍵ペアで復号できることを確認します。
12 * (差出人は受信者の公開鍵のみを知っていれば良い)。
13 */
14function demonstrateSodiumCryptoBoxSealOpen(): void
15{
16    // Sodium拡張が利用可能か確認します。
17    // PHP 7.2 以降では、libsodiumが標準でバンドルされています。
18    // 'php -m' コマンドで 'sodium' が表示されるか確認してください。
19    if (!extension_loaded('sodium')) {
20        echo "エラー: Sodium拡張が有効になっていません。PHPの設定を確認してください。\n";
21        return;
22    }
23
24    echo "--- Sodium 匿名公開鍵暗号化 (Seal/Open) デモンストレーション ---\n\n";
25
26    // 1. 受信者(メッセージを復号する側)の鍵ペアを生成します。
27    // この鍵ペアは、秘密鍵と公開鍵の両方を含みます。
28    // 秘密鍵は絶対に漏洩させてはいけません。
29    $recipientKeyPair = sodium_crypto_box_keypair();
30    $recipientPublicKey = sodium_crypto_box_publickey($recipientKeyPair);
31
32    echo "1. 受信者の鍵ペアを生成しました。\n";
33    echo "   公開鍵 (Recipient Public Key): " . bin2hex($recipientPublicKey) . "\n";
34    // セキュリティのため、秘密鍵は表示しません。
35
36    // 2. 暗号化する平文のメッセージを準備します。
37    $plaintext = "Hello, System Engineer beginner! This is a confidential message using asymmetric encryption.";
38    echo "\n2. 暗号化する平文 (Plaintext):\n\"" . $plaintext . "\"\n";
39
40    // 3. 受信者の公開鍵を使用してメッセージを暗号化します (Seal)。
41    // sodium_crypto_box_seal は、差出人の鍵ペアを必要とせず、受信者の公開鍵のみで暗号化します。
42    // この方式は「匿名」と呼ばれ、差出人は自分が送ったことを証明できません。
43    // 復号は受信者の秘密鍵でのみ可能です。
44    $ciphertext = sodium_crypto_box_seal($plaintext, $recipientPublicKey);
45    echo "\n3. 暗号化されたメッセージ (Ciphertext):\n\"" . bin2hex($ciphertext) . "\"\n";
46    echo "   (暗号文はバイナリデータなので、表示のために16進数に変換しています)\n";
47
48
49    // 4. 受信者の鍵ペアを使用して暗号文を復号します (Open)。
50    // sodium_crypto_box_seal_open には、暗号文と受信者の完全な鍵ペアが必要です。
51    $decryptedMessage = sodium_crypto_box_seal_open($ciphertext, $recipientKeyPair);
52
53    if ($decryptedMessage === false) {
54        echo "\n4. 復号に失敗しました。鍵ペアが正しくないか、暗号文が破損している可能性があります。\n";
55        return;
56    }
57
58    echo "\n4. 復号されたメッセージ (Decrypted Message):\n\"" . $decryptedMessage . "\"\n";
59
60    // 5. 復号されたメッセージが元の平文と一致するか検証します。
61    if ($decryptedMessage === $plaintext) {
62        echo "\n5. 検証成功: 復号されたメッセージは元の平文と完全に一致します。\n";
63        echo "   これにより、メッセージが正しく暗号化・復号されたことが確認されました。\n";
64    } else {
65        echo "\n5. 検証失敗: 復号されたメッセージが元の平文と一致しません。\n";
66        echo "   セキュリティ上の問題か、処理に誤りがある可能性があります。\n";
67    }
68
69    // 生成した鍵ペアをメモリからクリアします。
70    // セキュリティのベストプラクティスとして、機密データを使い終わったら消去します。
71    sodium_memzero($recipientKeyPair);
72}
73
74// 関数の実行
75demonstrateSodiumCryptoBoxSealOpen();
76

このPHPサンプルコードは、sodium_crypto_box_seal_open関数を使用して匿名公開鍵暗号におけるメッセージの復号をデモンストレーションします。この関数は、事前に秘密鍵を共有することなく、受信者の公開鍵のみで暗号化されたメッセージを、受信者の鍵ペアで安全に復号するために利用されます。

まず、メッセージを受け取る側の完全な鍵ペア(公開鍵と秘密鍵)を生成します。次に、この公開鍵を用いてsodium_crypto_box_seal関数で平文メッセージを暗号化し、これが外部から受信者へ送られた暗号文となります。

sodium_crypto_box_seal_open関数は、暗号化されたメッセージである$ciphertextと、メッセージを復号するための秘密鍵を含む受信者の$key_pairを引数として受け取ります。この関数が正常に処理を完了すると、復号された元の平文メッセージが文字列として返されます。しかし、指定された鍵ペアが正しくない場合や、暗号文が破損しているなど復号に失敗した場合には、セキュリティ上の理由から戻り値としてfalseが返されます。

サンプルコードでは、復号されたメッセージが元の平文と一致するかを検証し、暗号化および復号が正しく行われたことを確認しています。また、セキュリティのベストプラクティスとして、機密情報である鍵ペアを使い終えた後にsodium_memzeroでメモリから安全に消去する手順も示されています。

sodium_crypto_box_seal_open関数は、匿名公開鍵暗号化されたメッセージを受信者の完全な鍵ペアで復号します。この関数を使う上での注意点は、復号に必須の秘密鍵を厳重に管理し、絶対に漏洩させないことです。また、復号に失敗した場合はfalseが返されるため、必ず戻り値を確認し、エラーハンドリングを実装してください。暗号化されたメッセージ(暗号文)はバイナリデータであるため、データベース保存やネットワーク転送の際にはBase64などで適切にエンコードする必要があります。処理が完了したら、sodium_memzeroを用いてメモリ上の鍵情報を安全に消去することがセキュリティ上のベストプラクティスです。この方式は匿名であり、メッセージの送信者を検証する機能は含まれていません。

関連コンテンツ

関連IT用語

関連プログラミング言語