【PHP8.x】sodium_crypto_box()関数の使い方
sodium_crypto_box関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
sodium_crypto_box関数は、PHPのsodium拡張機能が提供する、メッセージを安全に暗号化し、認証を行うための強力な関数です。この関数は、送信者と受信者の間で、公開鍵と秘密鍵のペアを用いることで、第三者に内容を知られることなく、かつメッセージが改ざんされていないことを保証する安全な通信を実現します。
具体的には、送信者は自身の秘密鍵と受信者の公開鍵、そして一意の使い捨ての値であるnonce(ノンス)を使用してメッセージを暗号化します。これにより、メッセージの機密性が保たれるだけでなく、そのメッセージが正当な送信者によって送られ、途中で内容が変更されていないことを受信側で検証することが可能です。
システムエンジニアを目指す方にとって、WebアプリケーションやAPIにおける機密データの送受信において、この関数は堅牢なセキュリティを簡単に実装するための重要なツールとなります。高度な暗号技術の専門知識がなくても、安全な通信チャネルを確立できる点が大きな特長です。
構文(syntax)
1<?php 2 3// 暗号化したいメッセージ 4$message_to_encrypt = 'This is a secret message.'; 5 6// 暗号化に使用する一意のナンス(ランダムな値) 7$nonce_for_box = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES); 8 9// 送信者の秘密鍵と受信者の公開鍵を準備 10// 実際のアプリケーションでは、これらの鍵は安全な方法で生成・交換されます。 11$sender_secret_key = sodium_crypto_box_secretkey(sodium_crypto_box_keypair()); 12$recipient_public_key = sodium_crypto_box_publickey(sodium_crypto_box_keypair()); 13 14// sodium_crypto_box 関数で使用するためのキーペアを生成 15// これは送信者の秘密鍵と受信者の公開鍵を組み合わせたものです。 16$box_key_pair = sodium_crypto_box_keypair_from_secretkey_and_publickey( 17 $sender_secret_key, 18 $recipient_public_key 19); 20 21// sodium_crypto_box 関数の呼び出し構文 22$encrypted_data = sodium_crypto_box( 23 $message_to_encrypt, 24 $nonce_for_box, 25 $box_key_pair 26);
引数(parameters)
string $message, string $nonce, string $key_pair
- string $message: 暗号化するメッセージを指定する文字列
- string $nonce: ナンス(nonce)を指定する文字列。各メッセージで一意である必要があります。
- string $key_pair: 復号に必要な公開鍵と秘密鍵のペアを指定する文字列。sodium_crypto_box_keypair() などで生成されます。
戻り値(return)
string
暗号化されたメッセージ文字列を返します。
サンプルコード
PHP Sodium crypto_boxでメッセージを暗号化・復号化する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * PHP Sodium拡張を使ったメッセージの安全な送受信の例。 7 * sodium_crypto_box関数は、メッセージを認証付きで暗号化するために使用されます。 8 * これは主に、通信相手が事前に共有された公開鍵と秘密鍵ペアを持っているシナリオで使用されます。 9 */ 10function demonstrateSodiumCryptoBox(): void 11{ 12 // PHP Sodium拡張が利用可能か確認します。 13 // Sodiumは、モダンで安全な暗号化機能を提供するライブラリです。 14 // PHPでこれらの機能を使うには、Sodium拡張をインストールする必要があります。 15 if (!extension_loaded('sodium')) { 16 echo "エラー: PHP Sodium拡張がインストールされていません。\n"; 17 echo "このコードを実行するには、PHP Sodium拡張が必要です。\n"; 18 return; 19 } 20 21 echo "--- PHP Sodium crypto_box デモンストレーション ---\n\n"; 22 23 // 1. 送信者と受信者、それぞれの鍵ペアを生成します。 24 // 鍵ペアは「公開鍵」と「秘密鍵」のセットです。 25 // 公開鍵は誰にでも共有できますが、秘密鍵は絶対に他人に知られてはいけません。 26 $senderKeyPair = sodium_crypto_box_keypair(); 27 $recipientKeyPair = sodium_crypto_box_keypair(); 28 29 echo "送信者と受信者の鍵ペアが生成されました。\n"; 30 31 // 各鍵ペアから公開鍵と秘密鍵を抽出します。 32 $senderSecretKey = sodium_crypto_box_secretkey($senderKeyPair); 33 $senderPublicKey = sodium_crypto_box_publickey($senderKeyPair); 34 35 $recipientSecretKey = sodium_crypto_box_secretkey($recipientKeyPair); 36 $recipientPublicKey = sodium_crypto_box_publickey($recipientKeyPair); 37 38 // 2. 送信したい元のメッセージを定義します。 39 $originalMessage = 'これは極秘情報です。関係者以外閲覧禁止!'; 40 echo "元のメッセージ: " . $originalMessage . "\n"; 41 42 // 3. ノンス (Nonce) を生成します。 43 // ノンスは「Number Used Once(一度だけ使われる数値)」の略で、 44 // 同じ鍵ペアで複数のメッセージを暗号化する際に必須です。 45 // ノンスが毎回異なれば、攻撃者が既知の暗号文から元のメッセージを推測するのが非常に困難になります。 46 // SODIUM_CRYPTO_BOX_NONCEBYTES は、crypto_box関数が必要とするノンスの正確なバイト数を示します。 47 $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES); 48 echo "一意のノンスが生成されました (長さ: " . strlen($nonce) . "バイト)。\n"; 49 50 // 4. 送信者がメッセージを暗号化します。 51 // 暗号化には「送信者の秘密鍵」と「受信者の公開鍵」を組み合わせた鍵が必要です。 52 // sodium_crypto_box_keypair_from_secretkey_and_publickey 関数を使って、 53 // この2つの鍵から「通信用の共有鍵」を動的に作成します。 54 $senderToRecipientCombinedKey = sodium_crypto_box_keypair_from_secretkey_and_publickey( 55 $senderSecretKey, 56 $recipientPublicKey 57 ); 58 59 $encryptedMessage = sodium_crypto_box($originalMessage, $nonce, $senderToRecipientCombinedKey); 60 61 if ($encryptedMessage === false) { 62 echo "エラー: メッセージの暗号化に失敗しました。\n"; 63 return; 64 } 65 66 echo "メッセージが正常に暗号化されました (暗号文の長さ: " . strlen($encryptedMessage) . "バイト)。\n"; 67 // 暗号文はバイナリデータなので、そのまま表示すると読めない文字になります。 68 // echo "暗号文 (Base64エンコード): " . base64_encode($encryptedMessage) . "\n"; 69 70 // 5. 受信者がメッセージを復号化します。 71 // 復号化には「受信者の秘密鍵」と「送信者の公開鍵」を組み合わせた鍵が必要です。 72 // ここでも、sodium_crypto_box_keypair_from_secretkey_and_publickey 関数を使用します。 73 // また、暗号化時に使われたノンスも全く同じものである必要があります。 74 $recipientFromSenderCombinedKey = sodium_crypto_box_keypair_from_secretkey_and_publickey( 75 $recipientSecretKey, 76 $senderPublicKey 77 ); 78 79 $decryptedMessage = sodium_crypto_box_open( 80 $encryptedMessage, 81 $nonce, 82 $recipientFromSenderCombinedKey 83 ); 84 85 if ($decryptedMessage === false) { 86 echo "エラー: メッセージの復号化に失敗しました。\n"; 87 echo "鍵ペア、ノンス、または暗号文のいずれかが正しくない可能性があります。\n"; 88 return; 89 } 90 91 echo "メッセージが正常に復号化されました。\n"; 92 echo "復号化されたメッセージ: " . $decryptedMessage . "\n"; 93 94 // 復号化されたメッセージが元のメッセージと一致するか確認します。 95 if ($originalMessage === $decryptedMessage) { 96 echo "\n結果: 復号化されたメッセージは元のメッセージと完全に一致しました。安全な通信が成功しました。\n"; 97 } else { 98 echo "\n結果: エラー!復号化されたメッセージが元のメッセージと一致しませんでした。\n"; 99 } 100 echo "--------------------------------------------------\n"; 101} 102 103// デモンストレーション関数を実行します。 104demonstrateSodiumCryptoBox();
PHPのsodium_crypto_box関数は、モダンな暗号化ライブラリであるSodium拡張が提供する、メッセージを安全に送受信するための主要な機能です。これは、通信相手と事前に公開鍵と秘密鍵のペアを共有している状況で、メッセージを認証付きで暗号化するために使用されます。PHPでセキュリティの高い暗号化機能を利用したい場合に、Sodium拡張は広く推奨されています。
この関数は、引数として暗号化したい元のデータである$message、一度だけ使用される一意の数値である$nonce、そして送信者の秘密鍵と受信者の公開鍵を組み合わせた$key_pairを受け取ります。$nonceは、同じ鍵ペアで複数のメッセージを暗号化する際に必須で、毎回異なる値を設定することでセキュリティを強化します。$key_pairは、sodium_crypto_box_keypair_from_secretkey_and_publickey関数で動的に生成されます。
関数が正常に実行されると、暗号化されたデータが文字列として返されます。もし暗号化に失敗した場合はfalseが返されます。暗号化されたメッセージを復号化するには、sodium_crypto_box_open関数を使用し、暗号化時と全く同じ$nonceと、今度は受信者の秘密鍵と送信者の公開鍵を組み合わせた$key_pairが必要です。
このように、sodium_crypto_box関数は、データの機密性と完全性を保証し、第三者による盗聴や改ざんから通信を保護する強力な手段を提供します。PHPでセキュアなアプリケーションを開発する上で、Sodium拡張は非常に重要な役割を果たします。
このコードを実行するには、PHP Sodium拡張のインストールが必須です。秘密鍵は絶対に漏洩させず、厳重に管理してください。ノンス(nonce)はメッセージごとに必ず異なる値を生成し、暗号文と一緒に送信相手に渡す必要があります。同じノンスの再利用は、セキュリティを著しく低下させるため絶対に避けてください。暗号化と復号化では、使用する鍵ペアの組み合わせとノンスが完全に一致しないとメッセージの復号化に失敗します。また、sodium_crypto_box関数や関連関数の戻り値がfalseでないか、必ずエラーチェックを行ってください。Sodiumは、現代的で安全な暗号化通信を実現するために設計されています。
PHP Sodium: sodium_crypto_box 使い方
1<?php 2 3/** 4 * Demonstrates the usage of libsodium's public-key authenticated encryption. 5 * 6 * This function illustrates how to use `sodium_crypto_box` for encrypting a message 7 * from a sender (Alice) to a recipient (Bob), ensuring both confidentiality and 8 * authenticity (the message can only be decrypted by Bob, and Bob knows it came from Alice). 9 * 10 * It covers key generation, key context creation, encryption with `sodium_crypto_box`, 11 * and decryption with `sodium_crypto_box_open`. 12 */ 13function demonstrateSodiumCryptoBoxUsage(): void 14{ 15 // Ensure the Sodium extension is loaded 16 if (!extension_loaded('sodium')) { 17 echo "Error: The Sodium extension is not loaded. Please enable it in your PHP configuration.\n"; 18 return; 19 } 20 21 echo "--- PHP Sodium: Public-Key Authenticated Encryption (sodium_crypto_box) ---\n\n"; 22 23 // 1. Define the message to be encrypted 24 $originalMessage = "This is a secret message from Alice to Bob. Let's keep it safe!"; 25 echo "Original Message (Alice's side): \"$originalMessage\"\n\n"; 26 27 // 2. Generate key pairs for Alice (sender) and Bob (recipient) 28 // In a real-world scenario, these key pairs would be securely generated 29 // and exchanged out-of-band. For this example, we generate them locally. 30 $aliceKeyPair = sodium_crypto_box_keypair(); 31 $bobKeyPair = sodium_crypto_box_keypair(); 32 33 // Extract public and secret keys from the key pairs 34 $alicePublicKey = sodium_crypto_box_publickey($aliceKeyPair); 35 $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeyPair); 36 $bobPublicKey = sodium_crypto_box_publickey($bobKeyPair); 37 $bobSecretKey = sodium_crypto_box_secretkey($bobKeyPair); 38 39 echo "Alice and Bob have generated their public/secret key pairs.\n\n"; 40 41 // 3. Alice prepares to encrypt the message for Bob 42 // To encrypt, Alice needs her secret key and Bob's public key. 43 // These are combined into a "key context" for the encryption process. 44 $aliceToBobEncryptionKeyContext = sodium_crypto_box_keypair_from_secretkey_and_publickey( 45 $aliceSecretKey, 46 $bobPublicKey 47 ); 48 echo "Alice created an encryption key context using her secret key and Bob's public key.\n"; 49 50 // 4. Generate a unique nonce (number used once) for this message 51 // The nonce *must* be unique for every message encrypted with the same key context. 52 // It does not need to be secret but reusing it is a critical security vulnerability. 53 // The size of the nonce is fixed by SODIUM_CRYPTO_BOX_NONCEBYTES. 54 $nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES); 55 echo "Generated a unique " . SODIUM_CRYPTO_BOX_NONCEBYTES . "-byte nonce for this message.\n"; 56 57 // 5. Alice encrypts the message using `sodium_crypto_box` 58 try { 59 $cipherText = sodium_crypto_box($originalMessage, $nonce, $aliceToBobEncryptionKeyContext); 60 echo "Alice encrypted the message. Ciphertext length: " . strlen($cipherText) . " bytes.\n\n"; 61 } catch (SodiumException $e) { 62 echo "Error during encryption: " . $e->getMessage() . "\n"; 63 return; 64 } 65 66 // --- (The `cipherText` and `nonce` are now transmitted from Alice to Bob) --- 67 echo "--- (Ciphertext and Nonce transmitted from Alice to Bob) ---\n\n"; 68 69 // 6. Bob prepares to decrypt the message received from Alice 70 // To decrypt, Bob needs his secret key and Alice's public key. 71 // These are combined into a "key context" for the decryption process. 72 $bobFromAliceDecryptionKeyContext = sodium_crypto_box_keypair_from_secretkey_and_publickey( 73 $bobSecretKey, 74 $alicePublicKey 75 ); 76 echo "Bob created a decryption key context using his secret key and Alice's public key.\n"; 77 78 // 7. Bob decrypts the message using `sodium_crypto_box_open` 79 // He uses the received ciphertext, the received nonce, and his decryption key context. 80 try { 81 $decryptedMessage = sodium_crypto_box_open($cipherText, $nonce, $bobFromAliceDecryptionKeyContext); 82 83 if ($decryptedMessage === false) { 84 // Decryption can fail if the message was tampered with, or if the keys/nonce are incorrect. 85 echo "Decryption FAILED! The message could not be authenticated or was corrupted.\n"; 86 } else { 87 echo "Bob successfully decrypted the message.\n"; 88 echo "Decrypted Message (Bob's side): \"$decryptedMessage\"\n\n"; 89 90 // 8. Verify the decrypted message 91 if ($decryptedMessage === $originalMessage) { 92 echo "Verification: Decrypted message matches the original. Communication successful!\n"; 93 } else { 94 echo "Verification: Decrypted message DOES NOT match the original. Integrity compromised!\n"; 95 } 96 } 97 } catch (SodiumException $e) { 98 echo "Error during decryption: " . $e->getMessage() . "\n"; 99 } 100} 101 102// Execute the demonstration function 103demonstrateSodiumCryptoBoxUsage();
sodium_crypto_boxは、PHPのSodium拡張が提供する公開鍵暗号化関数で、メッセージの機密性と認証を同時に保証します。システムエンジニアを目指す方にとって、安全なデータ通信の基盤を学ぶ上で重要な機能です。
このサンプルコードでは、送信者(Alice)が受信者(Bob)へ秘密のメッセージを安全に送る一連の流れを実演しています。まず、AliceとBobがそれぞれ自身の公開鍵と秘密鍵のペアを生成します。メッセージを暗号化する際、Aliceは自身の秘密鍵とBobの公開鍵を組み合わせて、暗号化に使う「鍵コンテキスト」を作成します。
sodium_crypto_box関数は、暗号化したい元のメッセージ、メッセージごとに必ず異なる値を生成する必要がある「ナンス」、そして先ほど作成した鍵コンテキストの3つの引数を取ります。ナンスは再利用するとセキュリティ上の深刻な問題を引き起こすため、常に新しい値を生成することが重要です。この関数は、暗号化されたメッセージデータを文字列として返します。
Bobは、受信した暗号文とナンス、そして自身の秘密鍵とAliceの公開鍵から生成した復号化用の鍵コンテキストを使用して、sodium_crypto_box_open関数でメッセージを復号します。復号が成功すれば元のメッセージが取得できるだけでなく、メッセージが送信者によって確かに送られ、途中で改ざんされていないことも検証できます。これにより、安全で信頼性の高い通信が実現できるのです。
PHPのsodium_crypto_box関数を利用するには、まずSodium拡張機能が有効になっていることを確認してください。最も重要な注意点として、暗号化に使うNonce(ナンス)は、同じ鍵ペアで暗号化する際、決して使い回さないでください。毎回異なるランダムな値を生成し、暗号文と一緒に送信し、復号時に同じものを使用します。秘密鍵は厳重に管理し、漏洩がないようにしてください。また、sodium_crypto_box_open関数での復号に失敗しfalseが返された場合、メッセージが改ざんされたか、鍵やNonceが間違っている可能性がありますので、必ずこの戻り値を確認し、信頼できないメッセージは破棄することが安全な利用の必須条件です。