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

【PHP8.x】SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES定数の使い方

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

作成日: 更新日:

基本的な使い方

SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES定数は、libsodiumライブラリが提供するChaCha20-Poly1305 (IETF版) という認証付き暗号アルゴリズムにおいて、暗号化されたデータに付加される認証タグのバイト数(サイズ)を表す定数です。この定数の値は16バイトであり、データの機密性と完全性を同時に保証するために不可欠な認証タグの固定長を示します。

ChaCha20-Poly1305は、高速かつ安全な認証付き暗号方式として、ウェブアプリケーションなどでのデータ通信保護に利用されます。このアルゴリズムでは、データを暗号化するだけでなく、暗号文が改ざんされていないかを検証するための「認証タグ」を生成し、暗号文に付加します。認証タグは、データの真正性を証明し、不正な変更を検出する重要な役割を担います。

SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES定数を利用することで、開発者はChaCha20-Poly1305を用いた暗号化や復号の際に、認証タグが占める正確なバイト数を把握できます。これにより、暗号文全体の長さ計算や、復号時に認証タグの領域を正しく扱うことが可能となり、メモリ管理の正確性が向上し、セキュアなデータ処理の実装に貢献します。

構文(syntax)

1<?php
2echo SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES;

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

この定数は、ChaCha20-Poly1305暗号化アルゴリズム(IETF版)における、暗号文と認証タグの合計のバイト長を表す整数値を返します。

サンプルコード

PHP Sodium AEAD ChaCha20-Poly1305-IETF 暗号化/復号化

1<?php
2
3declare(strict_types=1);
4
5/**
6 * SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES 定数と関連機能のサンプルコード
7 *
8 * この関数は、PHP Sodium 拡張が提供する ChaCha20-Poly1305-IETF AEAD
9 * (Authenticated Encryption with Associated Data) アルゴリズムを使用して、
10 * データの暗号化と復号化を行います。
11 *
12 * 特に、認証タグのバイトサイズを示す SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES
13 * 定数と、ノンス (Nonce) のバイトサイズを示す SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES
14 * 定数が、暗号化処理においてどのように利用されるかを示します。
15 *
16 * @return void
17 */
18function demonstrateSodiumChacha20poly1305IetfEncryption(): void
19{
20    // PHP Sodium 拡張が利用可能かチェック
21    if (!extension_loaded('sodium')) {
22        echo "エラー: PHP Sodium 拡張がインストールされていません。";
23        return;
24    }
25
26    echo "--- PHP Sodium AEAD ChaCha20-Poly1305-IETF 暗号化/復号化サンプル ---\n\n";
27
28    // 1. 秘密鍵 (Key) の生成
29    // ChaCha20-Poly1305-IETF アルゴリズムでデータを保護するための秘密鍵を生成します。
30    // sodium_crypto_aead_chacha20poly1305_ietf_keygen() 関数は、このアルゴリズムに
31    // 適切なサイズの秘密鍵(32バイト)を生成します。
32    $key = sodium_crypto_aead_chacha20poly1305_ietf_keygen();
33    echo "生成された秘密鍵の長さ: " . strlen($key) . " バイト\n";
34
35    // 2. ノンス (Nonce) の生成
36    // ノンス (Number used once) は、同じ鍵で暗号化するたびに必ず異なる値を使用する必要があります。
37    // SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES 定数は、このアルゴリズムで
38    // 必要なノンスの正確なバイトサイズ(12バイト)を示します。
39    // セキュリティのために、この定数を使ってランダムなノンスを生成します。
40    $nonceBytes = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES;
41    $nonce = random_bytes($nonceBytes);
42    echo "ノンスの必須サイズ (SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES): " . $nonceBytes . " バイト\n";
43    echo "生成されたノンスの長さ: " . strlen($nonce) . " バイト\n\n";
44
45    // 3. プレーンテキスト (Plaintext) の準備
46    // 暗号化したい元のデータを定義します。
47    $plaintext = "システムエンジニアの皆さん、セキュリティは重要です!";
48    echo "元のプレーンテキスト: \"" . $plaintext . "\"\n";
49    echo "プレーンテキストの長さ: " . strlen($plaintext) . " バイト\n\n";
50
51    // 4. 関連データ (Associated Data - AD) の準備
52    // 関連データは暗号化されませんが、認証タグに含まれます。これにより、
53    // 関連データも改ざんされていないことが検証できます。
54    // 例: メッセージIDやユーザーIDなど、平文で扱うが認証が必要なデータに使用します。
55    $ad = "message_id: MSG-001 | user_id: USER-XYZ";
56    echo "関連データ (AD): \"" . $ad . "\"\n\n";
57
58    // 5. データの暗号化
59    // sodium_crypto_aead_chacha20poly1305_ietf_encrypt() 関数を使用してデータを暗号化します。
60    // この関数は、暗号化されたデータと認証タグの両方を含むバイナリ文字列を返します。
61    // SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES 定数は、この認証タグのサイズ(16バイト)を示します。
62    // したがって、暗号化後のデータの長さは「元のプレーンテキストの長さ + 認証タグの長さ」となります。
63    $ciphertextWithTag = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
64        $plaintext,  // 暗号化するデータ
65        $ad,         // 関連データ
66        $nonce,      // ノンス
67        $key         // 秘密鍵
68    );
69
70    $abytes = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES;
71    echo "認証タグの必須サイズ (SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES): " . $abytes . " バイト\n";
72    echo "暗号化されたデータの長さ (認証タグ含む): " . strlen($ciphertextWithTag) . " バイト\n";
73    echo "(期待される長さ: " . (strlen($plaintext) + $abytes) . " バイト)\n\n";
74
75    // 暗号化されたデータ(バイナリデータなのでそのまま表示すると文字化けする可能性があります)
76    // echo "暗号化されたデータ (Hex): " . bin2hex($ciphertextWithTag) . "\n\n";
77
78    // 6. データの復号化
79    // sodium_crypto_aead_chacha20poly1305_ietf_decrypt() 関数を使用してデータを復号化します。
80    // もし暗号化されたデータや関連データが改ざんされていた場合、復号化は失敗し、
81    // この関数は 'false' を返します(認証失敗)。
82    $decrypted = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
83        $ciphertextWithTag, // 暗号化されたデータ (認証タグ含む)
84        $ad,                // 暗号化時と同じ関連データ
85        $nonce,             // 暗号化時と同じノンス
86        $key                // 暗号化時と同じ秘密鍵
87    );
88
89    // 復号化の成功をチェック
90    if ($decrypted === false) {
91        echo "エラー: データの復号化に失敗しました。認証エラーかデータ改ざんの可能性があります。\n";
92    } else {
93        echo "復号化されたプレーンテキスト: \"" . $decrypted . "\"\n";
94        echo "復号化されたテキストの長さ: " . strlen($decrypted) . " バイト\n\n";
95
96        // 復号化されたデータが元のデータと一致するか検証
97        if ($plaintext === $decrypted) {
98            echo "検証成功: 復号化されたデータは元のプレーンテキストと一致します。\n";
99        } else {
100            echo "検証失敗: 復号化されたデータが元のプレーンテキストと一致しません。\n";
101        }
102    }
103
104    echo "\n--- サンプル終了 ---\n";
105}
106
107// 関数を実行してサンプルコードの動作を確認
108demonstrateSodiumChacha20poly1305IetfEncryption();

PHPのSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES定数は、Sodium拡張が提供するChaCha20-Poly1305-IETF暗号化アルゴリズムにおいて、データの認証に必要なタグのバイトサイズを示す整数値(int)です。この認証タグは、暗号化されたデータや付随する関連データが、通信中に改ざんされていないかを検証するために非常に重要です。

サンプルコードは、この定数と、同様にノンス(一度だけ使用される数値)のバイトサイズを示すSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES定数を活用した暗号化と復号化のプロセスを示しています。まず、sodium_crypto_aead_chacha20poly1305_ietf_keygen関数で秘密鍵を生成し、random_bytes関数で必要なサイズのノンスを作成します。次に、sodium_crypto_aead_chacha20poly1305_ietf_encrypt関数を使用して、プレーンテキストと関連データを秘密鍵、ノンスと共に暗号化します。この際、暗号化されたデータにはSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTESで定義されるサイズの認証タグが付加されるため、暗号文の全体の長さは元のデータよりも増加します。

復号化にはsodium_crypto_aead_chacha20poly1305_ietf_decrypt関数を使用します。この関数は、暗号文、暗号化時と同じ関連データ、ノンス、秘密鍵を引数として受け取ります。認証タグの検証に成功すれば復号されたプレーンテキストを返し、もしデータや関連データが改ざんされていた場合は認証に失敗し、戻り値としてfalseを返すことでセキュリティ侵害を検出します。このように、この定数はデータの機密性だけでなく、完全性と真正性を保証する上で不可欠な役割を担っています。

このサンプルコードで最も注意すべき点は、ノンス(Nonce)を必ず毎回異なるランダムな値で生成し、絶対に使い回さないことです。同じ鍵とノンスの組み合わせを再利用すると、暗号の安全性が著しく損なわれます。ノンスの生成には、SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES 定数が示す正確なバイトサイズを使用してください。また、復号化処理でfalseが返された場合、データが改ざんされた可能性があるので、必ずエラーとして処理してください。SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES 定数は、暗号化データに含まれる認証タグのバイトサイズを表しており、これによって暗号化後のデータ長が決定されます。秘密鍵は厳重に管理してください。

PHP Libsodium ChaCha20-Poly1305 AEAD暗号化・復号

1<?php
2
3/**
4 * Libsodiumライブラリを使用したChaCha20-Poly1305 (IETF) AEAD暗号化・復号のサンプル。
5 *
6 * この関数は、LibSodiumのChaCha20-Poly1305 (IETF) アルゴリズムを使って、
7 * データを安全に暗号化し、その後に復号する一連の処理を示します。
8 *
9 * SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES は、このアルゴリズムで
10 * 使用される認証タグ(Authentication Tag)のバイト長を示す定数です。
11 * 認証タグは、データの改ざんを検知するために暗号文に付加されます。
12 *
13 * AEAD (Authenticated Encryption with Associated Data) は、暗号化(機密性)と
14 * 認証(完全性)を同時に提供する強力な暗号方式です。
15 * なお、LibSodiumには他にもAES-256-GCMのような異なるAEADアルゴリズムも存在し、
16 * それぞれ異なる特性や関連する定数、関数(例えば `sodium_crypto_aead_aes256gcm_decrypt`)を持ちます。
17 *
18 * @param string $message 暗号化する元の平文データ。
19 * @param string $key 暗号化と復号に使用する秘密鍵。この鍵は SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES で
20 *                      定義された長さ(32バイト)である必要があります。
21 *                      安全に生成され、秘密に保たれるべきです。
22 * @param string $additionalData 認証のみを行う追加データ(AAD)。暗号化はされませんが、
23 *                               復号時にこのデータが改ざんされていないか検証されます。
24 *                               オプションであり、空文字列も可能です。
25 * @return array|false 成功時は ['ciphertext' => string, 'nonce' => string, 'decryptedMessage' => string] を含む配列、
26 *                     失敗時は false を返します。
27 * @throws InvalidArgumentException 鍵の長さが不適切な場合に発生します。
28 */
29function encryptAndDecryptChacha20Poly1305Ietf(string $message, string $key, string $additionalData = ''): array|false
30{
31    // 鍵の長さが Libsodium の要件に合致しているか検証
32    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES) {
33        throw new InvalidArgumentException(
34            '鍵の長さが正しくありません。' . SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES . ' バイトが必要です。'
35        );
36    }
37
38    // ノンス(Nonce)を生成します。
39    // ノンスは "Number used once" の略で、各暗号化操作で必ずユニークである必要があります。
40    // 再利用するとセキュリティ上の脆弱性につながります。
41    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
42
43    echo "--- 暗号化処理 ---" . PHP_EOL;
44    echo "使用アルゴリズム: ChaCha20-Poly1305 (IETF)" . PHP_EOL;
45    echo "認証タグ長 (ABYTES): " . SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES . " バイト" . PHP_EOL;
46    echo "ノンス長 (NPUBBYTES): " . SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES . " バイト" . PHP_EOL;
47    echo "元のメッセージ: '" . $message . "'" . PHP_EOL;
48    echo "追加データ (AAD): '" . $additionalData . "'" . PHP_EOL;
49
50    // メッセージの暗号化
51    // 戻り値の暗号文には、認証タグも含まれます。
52    $ciphertextWithTag = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
53        $message,
54        $additionalData,
55        $nonce,
56        $key
57    );
58
59    if ($ciphertextWithTag === false) {
60        echo "エラー: 暗号化に失敗しました。" . PHP_EOL;
61        return false;
62    }
63
64    echo "ノンス (Base64エンコード): " . base64_encode($nonce) . PHP_EOL;
65    echo "暗号文(認証タグ含む、Base64エンコード): " . base64_encode($ciphertextWithTag) . PHP_EOL;
66    echo "暗号文のバイト長: " . mb_strlen($ciphertextWithTag, '8bit') . " バイト" . PHP_EOL . PHP_EOL;
67
68    echo "--- 復号処理 ---" . PHP_EOL;
69    // 暗号文の復号
70    // 復号時に認証タグの検証も行われます。検証に失敗すると false を返します。
71    $decryptedMessage = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
72        $ciphertextWithTag,
73        $additionalData, // 暗号化時と同じ追加データを渡す必要がある
74        $nonce,          // 暗号化時と同じノンスを渡す必要がある
75        $key             // 暗号化時と同じ鍵を渡す必要がある
76    );
77
78    if ($decryptedMessage === false) {
79        echo "エラー: 復号に失敗しました。" . PHP_EOL;
80        echo "これは、認証タグの不一致、鍵の誤り、ノンスの誤り、またはデータが改ざんされたことを意味します。" . PHP_EOL;
81        return false;
82    }
83
84    echo "復号されたメッセージ: '" . $decryptedMessage . "'" . PHP_EOL;
85    echo "元のメッセージと復号されたメッセージの一致: " . ($message === $decryptedMessage ? "はい" : "いいえ") . PHP_EOL . PHP_EOL;
86
87    return [
88        'ciphertext' => $ciphertextWithTag,
89        'nonce' => $nonce,
90        'decryptedMessage' => $decryptedMessage,
91    ];
92}
93
94// --- 使用例 ---
95try {
96    // 1. 秘密鍵の生成
97    // 一度生成したら安全に保管し、暗号化・復号の両方で同じ鍵を使用します。
98    // 長さは SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES (32バイト) です。
99    $encryptionKey = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES);
100
101    $myMessage = "機密情報: 社外秘のプロジェクト計画書の内容です。";
102    $myAssociatedData = "ドキュメントID: P2024-001, 作成者: 田中";
103
104    // 2. 暗号化と復号の実行
105    $result = encryptAndDecryptChacha20Poly1305Ietf($myMessage, $encryptionKey, $myAssociatedData);
106
107    if ($result) {
108        echo "--- 改ざん検知のデモンストレーション ---" . PHP_EOL;
109
110        // 3.1. 暗号文の改ざんをシミュレート
111        echo "シナリオ1: 暗号文の改ざん" . PHP_EOL;
112        $tamperedCiphertext = $result['ciphertext'];
113        // 認証タグまたは暗号文の一部を意図的に変更
114        $tamperedCiphertext[0] = chr(ord($tamperedCiphertext[0]) ^ 0xFF); // 最初のバイトを反転させる
115
116        $decryptedTampered = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
117            $tamperedCiphertext,
118            $myAssociatedData,
119            $result['nonce'],
120            $encryptionKey
121        );
122
123        if ($decryptedTampered === false) {
124            echo "結果: 改ざんされた暗号文は正しく復号されませんでした(認証失敗)。これは期待通りのセキュリティ動作です。" . PHP_EOL . PHP_EOL;
125        } else {
126            echo "結果: 警告!改ざんされたはずの暗号文が復号されてしまいました。何らかの問題があります。" . PHP_EOL . PHP_EOL;
127        }
128
129        // 3.2. 追加データ (AAD) の改ざんをシミュレート
130        echo "シナリオ2: 追加データ (AAD) の改ざん" . PHP_EOL;
131        $tamperedAssociatedData = "ドキュメントID: P2024-002, 作成者: 田中"; // ドキュメントIDを変更
132
133        $decryptedTamperedAd = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
134            $result['ciphertext'],
135            $tamperedAssociatedData, // 異なる追加データで復号を試みる
136            $result['nonce'],
137            $encryptionKey
138        );
139
140        if ($decryptedTamperedAd === false) {
141            echo "結果: 追加データが改ざんされた場合も、正しく復号されませんでした(認証失敗)。これも期待通りのセキュリティ動作です。" . PHP_EOL . PHP_EOL;
142        } else {
143            echo "結果: 警告!追加データが改ざんされたはずなのに復号されてしまいました。何らかの問題があります。" . PHP_EOL . PHP_EOL;
144        }
145
146    } else {
147        echo "暗号化または復号処理に失敗したため、デモンストレーションを続行できません。" . PHP_EOL;
148    }
149
150} catch (Exception $e) {
151    echo "致命的なエラーが発生しました: " . $e->getMessage() . PHP_EOL;
152}

このサンプルコードは、PHP 8でLibSodium拡張機能を使用し、ChaCha20-Poly1305 (IETF) AEAD暗号アルゴリズムによるデータの暗号化と復号のプロセスを示しています。SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTESは、このアルゴリズムで生成される「認証タグ」のバイト長を定義する定数で、データの改ざんを検知するために暗号文に付加されます。AEAD (Authenticated Encryption with Associated Data) は、データの機密性(暗号化)だけでなく、その完全性(改ざんされていないこと)も同時に保証する強力な暗号方式です。

encryptAndDecryptChacha20Poly1305Ietf関数は、暗号化したいメッセージ、秘密鍵、そして認証のみを行う追加データ(AAD)を引数として受け取ります。関数内部では、一意のノンス(使い捨ての数値)を生成し、sodium_crypto_aead_chacha20poly1305_ietf_encryptでメッセージを暗号化します。暗号化されたデータには、SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTESで示される長さの認証タグが含まれます。その後、sodium_crypto_aead_chacha20poly1305_ietf_decryptで復号を試みますが、復号時には暗号文、ノンス、鍵、または追加データのいずれかが改ざんされていると、認証タグの検証に失敗し、復号が不可能となることでデータの完全性を保護します。関数は成功時に暗号文、ノンス、復号されたメッセージを含む配列を、失敗時にfalseを返します。このセキュリティ機能は、sodium_crypto_aead_aes256gcm_decryptのような他のAEADアルゴリズムでも共通しています。サンプルコードの後半では、この認証タグによる改ざん検知の仕組みをデモンストレーションしています。

このサンプルコードは、PHPのLibSodiumを用いた暗号化・復号の基本を示しています。最も重要な点は、使用する秘密鍵を安全に管理し、決して外部に漏らさないことです。また、ノンスは暗号化ごとに必ず異なる値を一度だけ使用してください。ノンスの再利用はセキュリティを著しく損ないます。AEADはデータの機密性と完全性を同時に保証するため、暗号化時と復号時で鍵、ノンス、および追加データがすべて一致する必要があります。不一致はデータの改ざん検知につながります。SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTESのような定数は、アルゴリズム固有の重要な情報を表すため、正しく理解し活用してください。エラー時のfalse戻り値も必ず確認し、適切な処理を実装することが安全なシステム運用に繋がります。

関連コンテンツ

関連IT用語

関連プログラミング言語