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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_aead_chacha20poly1305_decrypt関数は、ChaCha20-Poly1305という強力な認証付き暗号化アルゴリズムを用いて、暗号化されたデータを安全に復号する関数です。この関数は、単にデータを元の平文に復元するだけでなく、データが暗号化されてから改ざんされていないか、また正しい鍵によって暗号化されたかという認証を同時に実行します。これにより、データの機密性(不正な閲覧から保護されること)と完全性(意図しない変更が加えられていないこと)の両方を保証し、非常に安全なデータ処理を実現します。

この関数を使用する際には、復号したい暗号文、暗号化時に使用した秘密鍵、一度だけ使用されるべきユニークな数値ノンス(nonce)、そして認証の対象となる関連データ(additional_data)を引数として渡します。関連データは暗号化されませんが、認証の対象となり、データの完全性を高めるのに役立ちます。復号と認証に成功した場合、元の平文を文字列として返します。もし鍵が誤っている、ノンスが異なる、またはデータが改ざんされていると検出された場合など、認証に失敗した際にはfalseを返します。このfalseという戻り値を確認することで、不正なデータであるかを判断し、適切な処理を行うことができます。本関数は、PHPのSodium拡張機能が有効になっている環境で利用可能です。

構文(syntax)

1<?php
2$ciphertext = '';
3$additional_data = null;
4$nonce = '';
5$key = '';
6
7$decrypted_message = sodium_crypto_aead_chacha20poly1305_decrypt(
8    $ciphertext,
9    $additional_data,
10    $nonce,
11    $key
12);

引数(parameters)

string $ciphertext, string $additional_data, string $nonce, string $key

  • string $ciphertext: 復号化する暗号文を指定する文字列
  • string $additional_data: 認証に追加する追加データを指定する文字列
  • string $nonce: ナンス(一度だけ使用されるランダムな値)を指定する文字列
  • string $key: 復号化に使用する秘密鍵を指定する文字列

戻り値(return)

string|false

sodium_crypto_aead_chacha20poly1305_decrypt 関数は、ChaCha20-Poly1305 方式で暗号化されたデータを復号して元の平文文字列を返します。認証タグの検証に失敗した場合は false を返します。

サンプルコード

sodium_crypto_aead_chacha20poly1305_decryptによる認証付き複合化

1<?php
2
3/**
4 * プログラミング言語の専門家として、システムエンジニアを目指す初心者向けに
5 * `sodium_crypto_aead_chacha20poly1305_decrypt` 関数の使用例を生成します。
6 *
7 * この関数は、ChaCha20-Poly1305 アルゴリズムを用いて認証付き複合化を行います。
8 * 複合化の前に、対応する暗号化処理も示し、必要な引数を生成しています。
9 *
10 * PHP 8 の推奨コーディングスタイルに従い、単体で動作可能なコードです。
11 *
12 * @return void
13 */
14function demonstrateChaCha20Poly1305Decryption(): void
15{
16    // 1. 暗号化に使用する鍵を生成します。
17    // ChaCha20-Poly1305 の鍵長は 32 バイト(256ビット)です。
18    $key = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES);
19    echo "鍵 (Key): " . bin2hex($key) . PHP_EOL;
20
21    // 2. 暗号化する元の平文と、追加認証データ(AAD)を定義します。
22    // AAD は暗号化されませんが、複合化時に正当性を認証するために使用されます。
23    $plaintext = "システムエンジニアの皆さん、こんにちは!これは秘密のメッセージです。";
24    $additional_data = "user_id:42,message_type:private"; // オプションの追加認証データ
25
26    echo "元の平文 (Plaintext): " . $plaintext . PHP_EOL;
27    echo "追加認証データ (Additional Data): " . $additional_data . PHP_EOL;
28
29    // 3. 暗号化に使用するノンセ(nonce、一度だけ使用する番号)を生成します。
30    // ChaCha20-Poly1305 のノンセ長は 12 バイトです。
31    // 同じ鍵で暗号化するメッセージごとに、必ず異なるノンセを使用する必要があります。
32    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
33    echo "ノンセ (Nonce): " . bin2hex($nonce) . PHP_EOL;
34
35    // 4. `sodium_crypto_aead_chacha20poly1305_encrypt` を使用して平文を暗号化します。
36    // この関数は、暗号文と認証タグを結合した文字列を返します。
37    $ciphertext_with_tag = sodium_crypto_aead_chacha20poly1305_encrypt(
38        $plaintext,
39        $additional_data,
40        $nonce,
41        $key
42    );
43
44    if ($ciphertext_with_tag === false) {
45        echo "エラー: 暗号化に失敗しました。" . PHP_EOL;
46        return;
47    }
48    echo "暗号文と認証タグ (Ciphertext with Tag): " . bin2hex($ciphertext_with_tag) . PHP_EOL;
49
50    echo PHP_EOL . "--- 複合化のデモンストレーション ---" . PHP_EOL;
51
52    // 5. `sodium_crypto_aead_chacha20poly1305_decrypt` を使用して暗号文を複合化します。
53    // 引数として、暗号文、追加認証データ、ノンセ、鍵が必要です。
54    // 認証に成功し複合化された平文が返されるか、認証に失敗した場合は false が返されます。
55    $decrypted_plaintext = sodium_crypto_aead_chacha20poly1305_decrypt(
56        $ciphertext_with_tag,
57        $additional_data,
58        $nonce,
59        $key
60    );
61
62    // 6. 複合化の結果を確認します。
63    if ($decrypted_plaintext === false) {
64        echo "複合化に失敗しました!" . PHP_EOL;
65        echo "暗号文、追加認証データ、ノンセ、または鍵が誤っているか、データが改ざんされた可能性があります。" . PHP_EOL;
66    } else {
67        echo "複合化に成功しました!" . PHP_EOL;
68        echo "複合化された平文: " . $decrypted_plaintext . PHP_EOL;
69
70        // 元の平文と複合化された平文が一致するか検証
71        if ($decrypted_plaintext === $plaintext) {
72            echo "検証: 複合化された平文は元の平文と一致します。" . PHP_EOL;
73        } else {
74            echo "検証: 複合化された平文は元の平文と一致しません!" . PHP_EOL;
75        }
76    }
77
78    echo PHP_EOL . "--- 改ざんされたデータの複合化失敗デモンストレーション ---" . PHP_EOL;
79
80    // 7. 認証付き暗号化 (AEAD) の改ざん検知機能をデモンストレーションします。
81    // 暗号文を意図的に少し改ざんします。
82    $tampered_ciphertext_with_tag = $ciphertext_with_tag;
83    if (strlen($tampered_ciphertext_with_tag) > 0) {
84        // 暗号文の最初のバイトを反転させて改ざん
85        $tampered_ciphertext_with_tag[0] = chr(ord($tampered_ciphertext_with_tag[0]) ^ 0x01);
86    }
87
88    // 改ざんされた暗号文で複合化を試みます。
89    $failed_decryption_plaintext = sodium_crypto_aead_chacha20poly1305_decrypt(
90        $tampered_ciphertext_with_tag,
91        $additional_data,
92        $nonce,
93        $key
94    );
95
96    if ($failed_decryption_plaintext === false) {
97        echo "改ざんされた暗号文の複合化は期待通りに失敗しました。これは認証保護が機能していることを示します。" . PHP_EOL;
98    } else {
99        echo "エラー: 改ざんされた暗号文の複合化が成功しました!これはセキュリティ上の脆弱性を示します。" . PHP_EOL;
100        echo "複合化された平文: " . $failed_decryption_plaintext . PHP_EOL;
101    }
102}
103
104// デモンストレーション関数を実行します。
105demonstrateChaCha20Poly1305Decryption();
106
107?>

sodium_crypto_aead_chacha20poly1305_decrypt関数は、PHPのsodium拡張機能で提供される、ChaCha20-Poly1305という認証付き暗号化アルゴリズムを用いたデータの複合化を行います。この関数は、暗号化されたデータである$ciphertext、認証に使用される追加データ$additional_data、暗号化時に一度だけ使用される番号$nonce、そして共通鍵$keyの計4つの引数を必要とします。これらの引数は、暗号化時と完全に一致している必要があります。複合化処理では、まずデータの改ざんがないか、指定された鍵、追加データ、ノンセが正しいかを認証タグによって検証します。認証と複合化の両方が成功した場合に、元の平文が文字列として返されます。万が一、暗号文が改ざんされていたり、引数の一つでも不正確であったりした場合は、セキュリティ上の整合性が保てないと判断され、戻り値としてfalseが返されます。これにより、受信したデータが真正であり、安全に複合化されたかを確実に確認できるため、機密情報を扱うシステムにおいてデータの完全性と機密性を確保する上で非常に重要な役割を果たします。

sodium_crypto_aead_chacha20poly1305_decrypt関数は、認証された暗号文を複合化し、データが改ざんされていないかを確認する重要なセキュリティ機能です。安全に利用するためには、暗号化時に使用した鍵、ノンセ、追加認証データを完全に一致させて渡すことが必須となります。特にノンセは、同じ鍵で暗号化する各メッセージに対して一意である必要がありますので、使い回しは絶対に避けてください。もし暗号文やこれらの引数が少しでも異なったり、データが改ざんされていたりすると、認証失敗とみなされ、関数はセキュリティ保護のため必ずfalseを返します。したがって、関数の戻り値がfalseでないかを常に確認し、その場合はデータ改ざんや不正アクセスの可能性を考慮して処理を停止してください。暗号鍵の厳重な管理は、セキュリティ確保の最も基本的な要件です。

PHP sodium ChaCha20-Poly1305 AEAD 復号化

1<?php
2
3/**
4 * Libsodiumライブラリを使用して、ChaCha20-Poly1305アルゴリズムによる
5 * データの認証付き暗号化 (AEAD) と復号化を実演する関数です。
6 *
7 * AEADは、データの機密性(暗号化)と完全性・認証(改ざん検知)の両方を提供します。
8 * キーワードにある sodium_crypto_aead_aes256gcm_encrypt と同様に、
9 * ChaCha20-Poly1305も広く推奨されているAEADアルゴリズムの一つです。
10 *
11 * @param string $plaintext_input 暗号化する元のデータ(平文)
12 * @param string $additional_data_input 認証に含める追加データ。暗号化はされませんが、
13 *                                      復号化時にこのデータが改ざんされていないか検証されます。
14 * @return void 結果を標準出力に表示します。
15 */
16function demonstrateChacha20Poly1305AEAD(string $plaintext_input, string $additional_data_input = ''): void
17{
18    echo "--- ChaCha20-Poly1305 AEAD デモンストレーション ---" . PHP_EOL;
19    echo "暗号化する元の平文 (Plaintext): " . $plaintext_input . PHP_EOL;
20    echo "認証用の追加データ (Additional Data): " . ($additional_data_input ?: '[なし]') . PHP_EOL;
21    echo "----------------------------------------------------" . PHP_EOL;
22
23    // 1. 鍵 (Key) とノンス (Nonce) の生成
24    // 鍵は秘密に保管し、決して公開してはいけません。
25    // ノンスは暗号化ごとにユニーク(使い捨て)である必要があります。
26    // 同じ鍵で複数のデータを暗号化する場合は、毎回異なるノンスを生成して使用してください。
27    $key = sodium_crypto_aead_chacha20poly1305_keygen(); // 安全な乱数で鍵を生成
28    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES); // 必要なバイト数のノンスを生成
29
30    echo "生成された鍵 (Base64エンコード): " . base64_encode($key) . PHP_EOL;
31    echo "生成されたノンス (Base64エンコード): " . base64_encode($nonce) . PHP_EOL;
32    echo "----------------------------------------------------" . PHP_EOL;
33
34    // 2. データの暗号化 (sodium_crypto_aead_chacha20poly1305_encrypt)
35    // この関数は、平文、追加データ、ノンス、鍵を使用してデータを暗号化します。
36    // 戻り値は、暗号文と認証タグが結合された単一の文字列です。
37    $ciphertext = sodium_crypto_aead_chacha20poly1305_encrypt(
38        $plaintext_input,
39        $additional_data_input,
40        $nonce,
41        $key
42    );
43
44    if ($ciphertext === false) {
45        echo "エラー: 暗号化に失敗しました。" . PHP_EOL;
46        return;
47    }
48
49    echo "暗号化されたデータ (Ciphertext, Base64エンコード): " . base64_encode($ciphertext) . PHP_EOL;
50    echo "----------------------------------------------------" . PHP_EOL;
51
52    // 3. 暗号化されたデータの復号化 (sodium_crypto_aead_chacha20poly1305_decrypt)
53    // 復号化には、元の暗号文、追加データ、ノンス、鍵がすべて必要です。
54    // これらが一つでも不正な場合(例: キーが異なる、データが改ざんされた)、
55    // 復号化は失敗し `false` を返します。これはAEADの重要なセキュリティ機能です。
56    $decrypted_plaintext = sodium_crypto_aead_chacha20poly1305_decrypt(
57        $ciphertext,
58        $additional_data_input,
59        $nonce,
60        $key
61    );
62
63    if ($decrypted_plaintext === false) {
64        echo "エラー: 復号化に失敗しました。データが改ざんされたか、鍵/ノンス/追加データが間違っています。" . PHP_EOL;
65        return;
66    }
67
68    echo "復号化された平文 (Decrypted Plaintext): " . $decrypted_plaintext . PHP_EOL;
69    echo "----------------------------------------------------" . PHP_EOL;
70
71    // 4. 結果の検証
72    if ($plaintext_input === $decrypted_plaintext) {
73        echo "✓ 成功: データは正しく暗号化され、復号化されました。" . PHP_EOL;
74    } else {
75        echo "✗ 失敗: 復号化されたデータが元の平文と一致しませんでした。" . PHP_EOL;
76    }
77
78    // ----------------------------------------------------
79    // 5. セキュリティテスト: 改ざん検知の例
80    //    AEADの強力な機能の一つである「改ざん検知」を実演します。
81    // ----------------------------------------------------
82    echo PHP_EOL . "--- セキュリティテスト: 誤った鍵での復号化 ---" . PHP_EOL;
83    $wrong_key = sodium_crypto_aead_chacha20poly1305_keygen(); // 別の(不正な)鍵を生成
84    $attempt_decrypt_with_wrong_key = sodium_crypto_aead_chacha20poly1305_decrypt(
85        $ciphertext,
86        $additional_data_input,
87        $nonce,
88        $wrong_key // 不正な鍵を使用
89    );
90
91    if ($attempt_decrypt_with_wrong_key === false) {
92        echo "✓ 期待通り: 不正な鍵では復号化に失敗しました。(認証エラーにより 'false' を返却)" . PHP_EOL;
93    } else {
94        echo "✗ 警告: 不正な鍵で復号化に成功してしまいました。(これはあってはならない)" . PHP_EOL;
95    }
96
97    echo PHP_EOL . "--- セキュリティテスト: 追加データ改ざん ---" . PHP_EOL;
98    $altered_additional_data = "改ざんされた情報"; // 追加データを変更
99    $attempt_decrypt_with_altered_ad = sodium_crypto_aead_chacha20poly1305_decrypt(
100        $ciphertext,
101        $altered_additional_data, // 改ざんされた追加データを使用
102        $nonce,
103        $key
104    );
105
106    if ($attempt_decrypt_with_altered_ad === false) {
107        echo "✓ 期待通り: 改ざんされた追加データでは復号化に失敗しました。(認証エラーにより 'false' を返却)" . PHP_EOL;
108    } else {
109        echo "✗ 警告: 改ざんされた追加データで復号化に成功してしまいました。(これはあってはならない)" . PHP_EOL;
110    }
111}
112
113// -----------------------------------------------------------------------------
114// 関数呼び出し: デモンストレーションを実行します。
115// -----------------------------------------------------------------------------
116
117// 例1: 平文と追加データの両方を使用
118$my_secret_message = "このデータは絶対に誰にも見られてはいけません!";
119$related_info = "ドキュメントID: XYZ789, 作成者: Anonymous";
120demonstrateChacha20Poly1305AEAD($my_secret_message, $related_info);
121
122echo PHP_EOL . str_repeat('=', 70) . PHP_EOL . PHP_EOL;
123
124// 例2: 追加データなしの場合
125demonstrateChacha20Poly1305AEAD("追加データなしのシンプルな秘密のメッセージ");
126

PHPのsodium_crypto_aead_chacha20poly1305_decrypt関数は、LibSodiumライブラリを利用して、ChaCha20-Poly1305という強力な認証付き暗号 (AEAD) アルゴリズムで暗号化されたデータを復号化するために使われます。このAEADは、sodium_crypto_aead_aes256gcm_encrypt関数が扱うAES-256-GCMと同様に、データの機密性だけでなく、改ざんされていないことの検証(データの完全性と認証)も同時に行います。

この関数は、暗号化されたデータである$ciphertext、認証に利用された追加情報$additional_data、暗号化の際に一度だけ使用された数値$nonce、そして秘密鍵である$keyの計4つの文字列引数を受け取ります。復号化を成功させるためには、これらの引数が暗号化時に使用されたものと完全に一致している必要があります。

復号が正常に完了した場合、関数は元の平文を文字列として返します。しかし、何らかの理由で復号に失敗した場合はfalseを返します。この失敗は、渡された鍵、ノンス、追加データのいずれかが間違っているか、あるいは暗号文自体が不正に改ざんされていることを意味します。falseが返されることは、AEADアルゴリズムの重要なセキュリティ機能であり、不正なデータや操作から情報を守るための指標となります。この関数を理解することで、データの安全な取り扱いと、潜在的な改ざんへの対応を学ぶことができます。

sodium_crypto_aead_chacha20poly1305_decryptは、データの機密性と改ざん検知を同時に行う、安全な復号化関数です。復号化には、暗号文、秘密鍵、ユニークなノンス、そして暗号化時と同じ追加データが全て正しい状態で必要です。特に鍵は厳重に秘密に管理し、ノンスは暗号化ごとに必ず異なるものを利用してください。これらの情報が一つでも不正な場合、本関数は改ざんを検知し、安全のために復号を拒否してfalseを返します。そのため、戻り値がfalseでないか常に確認し、適切なエラーハンドリングを行うことが非常に重要です。キーワードにあるsodium_crypto_aead_aes256gcm_encryptと同様に、広く推奨される強力な認証付き暗号化アルゴリズムの一つとして利用できます。

関連コンテンツ

関連IT用語

関連プログラミング言語