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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_aead_xchacha20poly1305_ietf_encrypt関数は、XChaCha20-Poly1305アルゴリズムを使用して、データを認証付きで安全に暗号化を実行する関数です。この関数は、単にデータを秘密にするだけでなく、暗号化されたデータが通信中に改ざんされていないかを確認する「認証」の機能も提供します。これにより、データの機密性(秘密にすること)と完全性(改ざんされていないこと)の両方を強力に保証し、セキュリティを大幅に向上させます。

XChaCha20-Poly1305は、現代において推奨される強力な暗号化方式の一つであり、高速な処理能力と高いセキュリティレベルを兼ね備えています。特に、XChaCha20は一般的なChaCha20と比較して、暗号化に使用される一度きりの値(nonce)のサイズが拡張されており、これによりnonceの重複によるセキュリティリスクを低減し、より幅広い用途で安全に利用できる点が特徴です。

この関数を使用する際は、暗号化したい元のデータ(平文)、秘密鍵、そしてnonceと呼ばれる一度だけ使用する値を引数として指定します。さらに、オプションとして、認証の対象としたいが暗号化はしない追加のデータ(associated data)を指定することも可能です。これにより、例えば通信ヘッダ情報などが改ざんされていないことも認証で確認できるようになります。関数の戻り値は、暗号化されたデータと認証タグを含んだ文字列です。インターネットを介した機密データの通信や、データベースに保存する重要な情報の保護など、多岐にわたる場面で安全なシステムを構築するために不可欠な機能を提供します。

構文(syntax)

1<?php
2
3$message = '暗号化するメッセージ';
4$additionalData = '追加の認証データ(オプション)';
5$nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES); // 24バイトのノンスを生成
6$key = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES);     // 32バイトの鍵を生成
7
8$encryptedMessage = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
9    $message,
10    $additionalData,
11    $nonce,
12    $key
13);
14
15?>

引数(parameters)

string $message, string $additional_data, string $nonce, string $key

  • string $message: 暗号化する平文データを指定する文字列
  • string $additional_data: 認証のみを行う追加データを指定する文字列
  • string $nonce: ナンス(一度だけ使用する乱数)を指定する文字列
  • string $key: 鍵を指定する文字列

戻り値(return)

string

XChaCha20-Poly1305-IETFアルゴリズムを用いて、指定されたメッセージを暗号化し、認証タグを付加したバイナリ文字列を返します。

サンプルコード

PHP SodiumでXChaCha20-Poly1305暗号化する

1<?php
2
3/**
4 * PHPのSodium拡張を用いてXChaCha20-Poly1305暗号化と復号化を行うサンプルコードです。
5 * `sodium_crypto_aead_xchacha20poly1305_ietf_encrypt`関数の使用法を示します。
6 * キーワードであるnonceの長さの定数 `SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES`も使用しています。
7 *
8 * この関数は単体で動作し、メッセージの暗号化と復号化の一連の流れを示します。
9 * システムエンジニアを目指す初心者が、高レベルな暗号化APIの基本的な使い方を理解するのに役立ちます。
10 */
11function encryptAndDecryptWithXChaCha20Poly1305Example(): void
12{
13    // 暗号化・復号化する元のメッセージ
14    $originalMessage = 'これは重要な機密情報です。部外者には知られてはなりません。';
15
16    // 認証されるが暗号化されない追加データ (Associated Data)。
17    // 例えば、データベースのレコードIDなど、暗号文と一緒に検証したいが暗号化は不要な情報を指定します。
18    $additionalData = 'document_id: 456789';
19
20    echo "--- 暗号化処理開始 ---\n";
21    echo "元のメッセージ: " . $originalMessage . "\n";
22    echo "追加データ: " . $additionalData . "\n\n";
23
24    // 1. 暗号化キーの生成
25    // XChaCha20-Poly1305 (IETF) に必要な、安全なキーを生成します。
26    // sodium_crypto_aead_xchacha20poly1305_ietf_keygen() は推奨されるキー生成方法です。
27    // このキーは機密情報であり、安全に管理する必要があります。
28    $key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
29    echo "✔ 暗号化キーが安全に生成されました。\n";
30    // 実際のアプリケーションでは、このキーは環境変数、キー管理サービスなどからロードされます。
31
32    // 2. ナンス (Nonce) の生成
33    // ナンスは "Number used once" の略で、各暗号化操作でユニーク(一度だけ使われる)である必要があります。
34    // SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES は、XChaCha20-Poly1305 (IETF) に
35    // 必要なナンスの正確な長さをバイト単位で定義する定数です。
36    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
37    echo "✔ ナンスが指定された長さ (" . SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES . "バイト) で生成されました。\n";
38    // ナンスは機密情報ではありませんが、暗号文と一緒に保存し、復号化時に同じものを使用する必要があります。
39
40    // 3. メッセージの暗号化
41    // `sodium_crypto_aead_xchacha20poly1305_ietf_encrypt` 関数を使用してメッセージを暗号化します。
42    // この関数は、メッセージ、追加データ、ナンス、キーを受け取り、暗号文を返します。
43    try {
44        $cipherText = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
45            $originalMessage,
46            $additionalData,
47            $nonce,
48            $key
49        );
50        echo "✔ メッセージが正常に暗号化されました。\n";
51        // 暗号文はバイナリデータなので、表示のためにBase64エンコードします。
52        echo "暗号文 (Base64エンコード): " . base64_encode($cipherText) . "\n\n";
53    } catch (Throwable $e) {
54        echo "エラー: 暗号化に失敗しました: " . $e->getMessage() . "\n";
55        return;
56    }
57
58    echo "--- 復号化処理開始 ---\n";
59
60    // 4. メッセージの復号化
61    // `sodium_crypto_aead_xchacha20poly1305_ietf_decrypt` 関数を使用してメッセージを復号化します。
62    // 復号化には、元の暗号文、追加データ、ナンス、キーがすべて正確に一致している必要があります。
63    // 1バイトでも異なると復号に失敗し、認証タグの不一致 (MACが検証できない) によりエラーが発生します。
64    try {
65        $decryptedMessage = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
66            $cipherText,
67            $additionalData,
68            $nonce,
69            $key
70        );
71        echo "✔ メッセージが正常に復号化されました。\n";
72        echo "復号化されたメッセージ: " . $decryptedMessage . "\n\n";
73
74        // 復号化されたメッセージが元のメッセージと一致するか確認
75        if ($decryptedMessage === $originalMessage) {
76            echo "--- 結果 ---\n";
77            echo "✅ 復号化されたメッセージは元のメッセージと完全に一致します。";
78            echo "暗号化と復号化が成功しました。\n";
79        } else {
80            echo "--- 結果 ---\n";
81            echo "❌ 復号化されたメッセージは元のメッセージと一致しません。";
82            echo "何らかのエラーが発生した可能性があります。\n";
83        }
84    } catch (Throwable $e) {
85        echo "エラー: 復号化に失敗しました。データが改ざんされたか、キー/ナンス/追加データが間違っています: " . $e->getMessage() . "\n";
86        return;
87    }
88}
89
90// 関数を実行して、暗号化と復号化のフローを確認します。
91encryptAndDecryptWithXChaCha20Poly1305Example();

PHPのSodium拡張が提供するsodium_crypto_aead_xchacha20poly1305_ietf_encrypt関数は、XChaCha20-Poly1305 (IETF) アルゴリズムを用いてデータを安全に暗号化する高レベルなAPIです。この関数は、暗号化したい元のデータである$message、認証されるが暗号化はされない追加データである$additional_data、各暗号化操作で一意に生成されるナンスである$nonce、そして秘密の暗号化キーである$keyの四つの引数を受け取ります。ナンスはキーワードであるSODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES定数で定義される正確な長さで生成する必要があり、セキュリティ上の理由から決して再利用してはいけません。関数の戻り値は、暗号化された元のメッセージと、データが改ざんされていないかを検証するための認証タグを含むバイナリ文字列です。$additional_dataは暗号文と共に保存され、復号時に内容が変更されていないかを確認するために利用されます。このサンプルコードは、安全なキーとナンスの生成からメッセージの暗号化、そして復号化までの一連の流れを示し、復号時の認証失敗によるエラーハンドリングの重要性も理解できます。これにより、システムエンジニアを目指す初心者の方が、安全なデータ保護を実現するための基本的な暗号化APIの使い方を学ぶことができます。

このサンプルコードで示される暗号化キーは機密情報のため、実際のシステムでは環境変数やキー管理サービスを用いて厳重に管理してください。ナンス(Nonce)は、各暗号化操作で必ず異なるユニークな値を用いる必要があり、SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES定数で定められた正しい長さを確保して生成します。ナンスは暗号文と共に保管し、復号時に同じものを使用してください。追加データは、復号時にキー、ナンス、暗号文と完全に一致させる必要があります。一つでも異なる場合、データ改ざんとみなされ復号は失敗します。暗号化や復号の処理は失敗する可能性があるため、必ずtry-catchブロックで適切なエラーハンドリングを実装してください。また、暗号化されたデータはバイナリ形式のため、テキストとして表示したりデータベースに保存する際は、Base64エンコードなどを利用すると良いでしょう。

PHP Sodium XChaCha20-Poly1305 暗号化・復号する

1<?php
2
3/**
4 * Demonstrates encryption and decryption using Sodium's XChaCha20-Poly1305 (IETF variant).
5 *
6 * This function showcases `sodium_crypto_aead_xchacha20poly1305_ietf_encrypt`
7 * and its corresponding decryption function, which is highly related to the concept
8 * of `sodium_crypto_aead_aes256gcm_decrypt` by illustrating the complete AEAD cycle.
9 *
10 * Requirements: PHP 7.2+ with the Sodium extension enabled.
11 */
12function demonstrateSodiumAeadXChaCha20Poly1305IetfEncryption(): void
13{
14    // 1. Generate a secure random key for XChaCha20-Poly1305 (IETF variant).
15    // The key length is fixed and automatically handled by sodium_crypto_aead_xchacha20poly1305_ietf_keygen().
16    $key = sodium_crypto_aead_xchacha20poly1305_ietf_keygen();
17    echo "Generated Key (hex, for debug purposes, DO NOT LOG IN PRODUCTION): " . bin2hex($key) . "\n\n";
18
19    // 2. Define the message string to be encrypted.
20    $message = "This is a confidential message that needs to be secured.";
21    echo "Original Message: " . $message . "\n";
22
23    // 3. Define optional additional authenticated data (AAD).
24    // This data is authenticated alongside the message but not encrypted.
25    // It's useful for binding the ciphertext to specific context information (e.g., user ID, document ID).
26    // If tampered with during decryption, the entire decryption will fail.
27    $additionalData = "user_id:123, transaction_id:abc";
28    echo "Additional Data: " . $additionalData . "\n";
29
30    // 4. Generate a unique nonce (number used once).
31    // This MUST be unique for every encryption with the same key. Reusing a nonce
32    // with the same key is a critical security vulnerability.
33    // The length is fixed for XChaCha20-Poly1305 (IETF variant).
34    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
35    echo "Generated Nonce (hex, for debug purposes, DO NOT LOG IN PRODUCTION): " . bin2hex($nonce) . "\n\n";
36
37    // --- Encryption Process ---
38    echo "--- Encryption Process ---\n";
39    try {
40        // Encrypt the message using sodium_crypto_aead_xchacha20poly1305_ietf_encrypt.
41        // The output includes the ciphertext concatenated with the authentication tag.
42        $encryptedMessage = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
43            $message,
44            $additionalData,
45            $nonce,
46            $key
47        );
48        echo "Encrypted Message (base64 encoded for display): " . base64_encode($encryptedMessage) . "\n\n";
49    } catch (SodiumException $e) {
50        // Handle encryption errors, e.g., invalid key length.
51        echo "Encryption failed: " . $e->getMessage() . "\n";
52        return;
53    }
54
55    // --- Decryption Process ---
56    echo "--- Decryption Process ---\n";
57    try {
58        // Decrypt the message using sodium_crypto_aead_xchacha20poly1305_ietf_decrypt.
59        // It requires the exact same encrypted message, additional_data, nonce, and key
60        // used for encryption. If any of these are incorrect or have been tampered with,
61        // decryption will fail and return `false`, preventing silent data corruption.
62        $decryptedMessage = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
63            $encryptedMessage,
64            $additionalData,
65            $nonce, // The same nonce used for encryption
66            $key    // The same key used for encryption
67        );
68
69        if ($decryptedMessage === false) {
70            echo "Decryption failed: Message, additional data, key, or nonce was incorrect or tampered with.\n";
71        } else {
72            echo "Decrypted Message: " . $decryptedMessage . "\n";
73            if ($decryptedMessage === $message) {
74                echo "Decryption successful! The original message was recovered.\n";
75            } else {
76                echo "Decryption successful, but the message content mismatch occurred (this indicates an error in the logic).\n";
77            }
78        }
79    } catch (SodiumException $e) {
80        // Handle decryption errors.
81        echo "Decryption failed (exception): " . $e->getMessage() . "\n";
82    }
83}
84
85// Execute the demonstration function.
86demonstrateSodiumAeadXChaCha20Poly1305IetfEncryption();

PHPのsodium_crypto_aead_xchacha20poly1305_ietf_encrypt関数は、機密性の高いデータを安全に暗号化するための機能を提供します。このサンプルコードは、XChaCha20-Poly1305 (IETF variant) という現代的な暗号方式を用いて、メッセージを暗号化し、その後に復号する一連の流れを実演しています。

sodium_crypto_aead_xchacha20poly1305_ietf_encrypt関数は、4つの引数を受け取ります。第一引数$messageは暗号化したい元の文字列です。第二引数$additional_dataは、メッセージと共に認証したい追加情報で、暗号化はされませんが復号時に改ざんの有無を検証するために使われます。例えばユーザーIDなどを含めることで、暗号文とそのコンテキストを紐付けられます。第三引数$nonceは「ナンバー・ユーズド・ワンス」を意味し、同じキーで暗号化するたびに必ず異なる値を使用する必要がある非常に重要な引数です。これを再利用すると重大なセキュリティ脆弱性につながります。第四引数$keyは、暗号化と復号の両方に使用される秘密鍵で、安全に生成され厳重に管理される必要があります。

この関数は、元のメッセージと認証タグが結合された暗号文(文字列)を戻り値として返します。この暗号文は、対応するsodium_crypto_aead_xchacha20poly1305_ietf_decrypt関数によってのみ、暗号化時と全く同じ$additional_data$nonce$keyが揃った場合に元のメッセージに復号できます。もしこれらの引数のいずれかが間違っていたり、暗号文や追加データが改ざんされていたりした場合、復号は失敗し、falseが返されるか例外が発生します。これは、sodium_crypto_aead_aes256gcm_decryptなどの他のAEAD(Authenticated Encryption with Associated Data)暗号方式と同様に、データの機密性と完全性の両方を保証する仕組みであり、データの盗聴や改ざんから情報を保護します。

この関数はメッセージの暗号化に利用されますが、特にノンス(nonce)の管理が非常に重要です。同じ鍵で暗号化する際は、毎回必ず異なるユニークなノンスを生成し使用してください。ノンスを使い回すと、セキュリティ上の致命的な脆弱性につながります。鍵(key)もsodium_crypto_aead_xchacha20poly1305_ietf_keygen()で安全に生成し、厳重に管理して決して外部に公開しないでください。追加認証データ(additional_data)は暗号化されませんが、復号時に改ざんが検知されるため、メッセージと関連する情報を渡す際に活用できます。エラーが発生した場合はSodiumExceptionを捕捉し、復号時にはfalseが返る可能性があるため、戻り値を適切にチェックしてください。

関連コンテンツ

関連IT用語

関連プログラミング言語