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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_aead_chacha20poly1305_ietf_decrypt関数は、PHPのLibsodium拡張機能が提供する、国際的な標準規格であるChaCha20-Poly1305 IETFバージョンを利用して、暗号化されたデータを安全に復号する関数です。この関数は、認証付き暗号(AEAD)と呼ばれる高度な暗号化手法に対応しており、単にデータを元の状態に戻すだけでなく、そのデータが途中で改ざんされていないか(完全性)、そして正当な送信元からのものであるか(認証)を同時に検証します。これにより、データの機密性はもちろん、信頼性も確保されます。

この関数を使用する際は、暗号化時に生成された暗号文、秘密鍵、そして一度だけ使用される一意の値であるノンス(nonce)を必須の引数として指定します。また、オプションとして、暗号文自体には含まれないものの、認証の対象とする関連データ(associated data)も指定できます。これらの情報が一つでも正しくない場合や、データが不正に改変されている場合は、復号に失敗し、ブール値のfalseを返します。成功した場合は、復号された元のプレーンテキスト(平文)データをバイナリ文字列として返します。この機能は、セキュアな通信路の構築や、データベースに保存された機密情報の保護など、データセキュリティが極めて重要となる場面で幅広く活用されています。

構文(syntax)

1<?php
2$ciphertext = '';
3$additional_data = null;
4$nonce = '';
5$key = '';
6
7$decrypted_data = sodium_crypto_aead_chacha20poly1305_ietf_decrypt($ciphertext, $additional_data, $nonce, $key);

引数(parameters)

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

  • string $ciphertext: 復号化する暗号化されたデータ(文字列)
  • string $additional_data: 認証のみを行う追加データ(文字列)
  • string $nonce: データを一意にするためのノンス(文字列)
  • string $key: 復号化に使用する秘密鍵(文字列)

戻り値(return)

string|false

入力された認証付き暗号文を複合し、元の平文を文字列として返します。複合に失敗した場合は false を返します。

サンプルコード

PHP Libsodium: ChaCha20-Poly1305 IETF 復号処理

1<?php
2
3/**
4 * LibsodiumのChaCha20-Poly1305 (IETF) AEAD暗号化方式を用いた復号化のデモンストレーションを行います。
5 * この関数は、`sodium_crypto_aead_chacha20poly1305_ietf_decrypt` 関数の使い方を示し、
6 * キーワードである `sodium_crypto_aead_chacha20poly1305_ietf_npubbytes` を用いたナンスの生成を含みます。
7 *
8 * @return void
9 */
10function demonstrateAeadChacha20Poly1305IetfDecryption(): void
11{
12    // 1. 秘密鍵の生成
13    // ChaCha20-Poly1305 (IETF) 暗号化方式で使用する秘密鍵を生成します。
14    // この鍵は暗号化と復号化の両方で必要です。
15    $key = sodium_crypto_aead_chacha20poly1305_ietf_keygen();
16
17    // 2. ナンス (Nonce) の生成
18    // ナンスは、各暗号化操作で一度だけ使用される一意の値です。
19    // `sodium_crypto_aead_chacha20poly1305_ietf_npubbytes()` は、
20    // この暗号化方式で必要なナンスのバイト数を返します。
21    // `random_bytes()` を使用して、その長さのランダムなナンスを生成します。
22    $nonce = random_bytes(sodium_crypto_aead_chacha20poly1305_ietf_npubbytes());
23
24    // 3. 平文 (元のメッセージ) の準備
25    // 暗号化するメッセージです。
26    $plaintext = 'これは極秘のメッセージであり、安全に暗号化および復号化される必要があります。';
27
28    // 4. 追加認証データ (Additional Data) の準備
29    // このデータは暗号化されませんが、認証プロセスに含まれます。
30    // 復号時にこのデータが元の暗号化時のものと異なる場合、認証が失敗し、復号も失敗します。
31    $additionalData = 'このメッセージのメタデータや関連情報';
32
33    echo "元の平文: " . $plaintext . PHP_EOL;
34    echo "追加認証データ: " . $additionalData . PHP_EOL . PHP_EOL;
35
36    // 5. データの暗号化
37    // `sodium_crypto_aead_chacha20poly1305_ietf_encrypt` を使用して、平文を暗号化します。
38    // 戻り値は認証タグを含む暗号文です。
39    $ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
40        $plaintext,      // 暗号化する平文
41        $additionalData, // 認証に含める追加データ
42        $nonce,          // 一意のナンス
43        $key             // 秘密鍵
44    );
45
46    echo "暗号文 (Base64エンコード): " . base64_encode($ciphertext) . PHP_EOL . PHP_EOL;
47
48    // 6. データの復号化
49    // `sodium_crypto_aead_chacha20poly1305_ietf_decrypt` を使用して、暗号文を復号化します。
50    // 暗号文が改ざんされていたり、ナンス、鍵、または追加認証データが一致しない場合、
51    // 復号は失敗し、`false` を返します。
52    $decryptedText = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
53        $ciphertext,      // 復号する暗号文
54        $additionalData,  // 暗号化時と同じ追加認証データ
55        $nonce,           // 暗号化時と同じナンス
56        $key              // 暗号化時と同じ秘密鍵
57    );
58
59    // 7. 復号結果の確認
60    if ($decryptedText === false) {
61        echo "復号に失敗しました!データが改ざんされたか、またはパラメータが誤っています。" . PHP_EOL;
62    } else {
63        echo "復号に成功しました!" . PHP_EOL;
64        echo "復号された平文: " . $decryptedText . PHP_EOL;
65
66        // 復号されたデータが元の平文と一致するか確認します。
67        if ($decryptedText === $plaintext) {
68            echo "検証成功: 復号されたテキストは元の平文と一致します。" . PHP_EOL;
69        } else {
70            echo "検証失敗: 復号されたテキストは元の平文と一致しません。(これは通常発生しません)" . PHP_EOL;
71        }
72    }
73
74    echo PHP_EOL . "--- 復号失敗の例 (セキュリティ検証) ---" . PHP_EOL;
75
76    // 復号失敗の例:異なる追加認証データを使用した場合
77    // 実際のアプリケーションでは、攻撃者が追加認証データを変更しようとすると、
78    // このように復号が失敗し、データの改ざんを検出できます。
79    $modifiedAdditionalData = '改ざんされたメタデータ';
80    echo "改ざんされた追加認証データ: '" . $modifiedAdditionalData . "' を使用して復号を試みます。" . PHP_EOL;
81    $failedDecryption = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
82        $ciphertext,
83        $modifiedAdditionalData, // 意図的に変更された追加認証データ
84        $nonce,
85        $key
86    );
87
88    if ($failedDecryption === false) {
89        echo "期待通り、追加認証データの改ざんにより復号が失敗しました。" . PHP_EOL;
90    } else {
91        echo "予期せず復号が成功しました!(これはセキュリティ上の問題を示します)" . PHP_EOL;
92    }
93}
94
95// 上記のデモンストレーション関数を実行します。
96// Libsodium拡張機能が有効になっている環境で実行してください。
97demonstrateAeadChacha20Poly1305IetfDecryption();
98
99?>

PHPのsodium_crypto_aead_chacha20poly1305_ietf_decrypt関数は、高度なChaCha20-Poly1305 (IETF) AEAD暗号方式で暗号化されたデータを元の形に戻す(復号する)ために使用されます。AEAD(Authenticated Encryption with Associated Data)は、単にデータを秘密にするだけでなく、データが途中で改ざんされていないことを確認する認証機能も持ち、さらに暗号化されない追加情報も認証対象に含めることができる点が特徴です。

この関数には4つの引数が必要です。$ciphertextは復号したい暗号文、$additional_dataは暗号化時に指定した、認証の対象となる付随データ、$nonceは暗号化時に使用された、各操作で一意であるべき値、そして$keyは暗号化と復号で共通の秘密鍵です。これらの引数が暗号化時と完全に一致しないと復号は成功しません。特にナンスはsodium_crypto_aead_chacha20poly1305_ietf_npubbytes()関数で適切な長さを取得し、ランダムに生成することが推奨されます。

復号が成功した場合、関数は元の平文(暗号化される前のデータ)を文字列として返します。しかし、暗号文が改ざんされていたり、$additional_data$nonce$keyのいずれかが暗号化時のものと異なっていたりすると、セキュリティ上の理由からfalseを返します。この挙動により、データの不正な変更を検出し、安全な復号処理を提供します。

PHPのsodium_crypto_aead_chacha20poly1305_ietf_decrypt関数で復号する際は、暗号化時に使った秘密鍵、ナンス、追加認証データが完全に一致している必要があります。これらの一つでも異なると復号は失敗し、falseが返されます。特にナンスは、各暗号化で必ず異なるユニークな値をsodium_crypto_aead_chacha20poly1305_ietf_npubbytes()で得られるバイト数で生成してください。また、関数がfalseを返す場合は、暗号文の改ざんや引数の不一致を意味しますので、必ず戻り値を厳密にチェックし、適切にエラー処理を行うことが重要です。この機能はPHPのLibsodium拡張機能に依存しています。

sodium_crypto_aead_chacha20poly1305_ietf_decrypt でデータを復号する

1<?php
2
3/**
4 * LibsodiumのChaCha20-Poly1305 (IETF variant) を用いてデータを復号するサンプル。
5 *
6 * この関数は、`sodium_crypto_aead_chacha20poly1305_ietf_decrypt` の使い方を示します。
7 * 暗号化されたデータ、追加認証データ、ナンス、鍵を引数として受け取り、
8 * 復号された平文を返します。
9 *
10 * セキュリティ上の理由から、鍵とナンスは適切に生成し、管理する必要があります。
11 * ナンスは各暗号化操作でユニークである必要があります。
12 *
13 * @param string $ciphertext 暗号文。
14 * @param string $additional_data 認証されるが暗号化されない追加データ(オプション)。
15 * @param string $nonce 各暗号化操作で一意なナンス。
16 * @param string $key 暗号化に使用された秘密鍵。
17 * @return string|false 復号された平文、または復号に失敗した場合は false。
18 */
19function decryptWithChacha20Poly1305Ietf(
20    string $ciphertext,
21    string $additional_data,
22    string $nonce,
23    string $key
24): string|false {
25    // sodium_crypto_aead_chacha20poly1305_ietf_decrypt 関数を使用して復号
26    // 復号に成功すると元の平文が、失敗すると false が返されます。
27    return sodium_crypto_aead_chacha20poly1305_ietf_decrypt(
28        $ciphertext,
29        $additional_data,
30        $nonce,
31        $key
32    );
33}
34
35// --- サンプルコードの実行例 ---
36
37// Libsodiumが利用可能かチェック
38if (!extension_loaded('sodium')) {
39    echo "エラー: sodium 拡張機能がロードされていません。\n";
40    exit(1);
41}
42
43echo "--- ChaCha20-Poly1305 (IETF variant) 復号サンプル ---\n\n";
44
45// 1. 秘密鍵の生成 (一度生成したら安全に保存・再利用します)
46// 鍵の長さは SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES で定義されています (32バイト)。
47$key = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES);
48echo "生成された鍵: " . bin2hex($key) . "\n\n";
49
50// 2. ナンスの生成 (各暗号化操作で必ず一意である必要があります)
51// ナンスの長さは SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES で定義されています (12バイト)。
52$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
53echo "生成されたナンス: " . bin2hex($nonce) . "\n\n";
54
55// 3. 平文と追加認証データ (Additional Data) の準備
56$originalPlaintext = "これは秘密のメッセージです。誰にも読まれたくない!";
57$additionalData = "ユーザーID:12345, ファイル名:document.pdf"; // 認証するが暗号化しないデータ
58echo "元の平文: " . $originalPlaintext . "\n";
59echo "追加認証データ: " . $additionalData . "\n\n";
60
61// 4. データ暗号化 (復号の引数を準備するために必要です)
62// 実際には、この暗号文はどこかから取得されることになります。
63$ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt(
64    $originalPlaintext,
65    $additionalData,
66    $nonce,
67    $key
68);
69echo "暗号文 (hex): " . bin2hex($ciphertext) . "\n\n";
70
71// 5. 復号処理
72echo "復号を開始します...\n";
73$decryptedPlaintext = decryptWithChacha20Poly1305Ietf(
74    $ciphertext,
75    $additionalData,
76    $nonce,
77    $key
78);
79
80// 6. 復号結果の確認
81if ($decryptedPlaintext !== false) {
82    echo "復号に成功しました!\n";
83    echo "復号された平文: " . $decryptedPlaintext . "\n";
84
85    // 元の平文と一致するか確認
86    if ($decryptedPlaintext === $originalPlaintext) {
87        echo "元の平文と一致します。検証成功。\n";
88    } else {
89        echo "エラー: 復号された平文が元の平文と一致しません。\n";
90    }
91} else {
92    // 復号に失敗した場合、改ざんされたか、鍵・ナンス・追加データが不正であった可能性があります。
93    echo "エラー: 復号に失敗しました。データが改ざんされたか、鍵/ナンス/追加データが正しくありません。\n";
94}
95
96echo "\n--- サンプル終了 ---";
97
98?>

この関数は、PHPのLibsodium拡張機能を用いて、ChaCha20-Poly1305 (IETF variant) という強力な暗号アルゴリズムで暗号化されたデータを復号するために使用されます。データが暗号化される際に使用された$ciphertext(暗号文)、$additional_data(追加認証データ)、$nonce(ナンス)、$key(秘密鍵)を引数として受け取ります。

$ciphertextは暗号化された実際のデータ、$additional_dataは暗号化されませんが、データの完全性を保証するために認証される補助情報です。$nonceは各暗号化操作で必ず一意である必要がある使い捨ての数値で、セキュリティ上非常に重要です。$keyはデータを暗号化した際に使われた秘密鍵であり、厳重に管理する必要があります。

この関数は、復号に成功した場合、元の平文を文字列として返します。もし、提供されたデータが改ざんされていたり、鍵、ナンス、または追加認証データが暗号化時と異なっていたりすると、復号に失敗しfalseを返します。サンプルコードでは、鍵とナンスの生成からデータの暗号化、そして本関数による復号までの一連のプロセスが示されており、特に鍵とナンスの重要性とその管理方法を理解するのに役立ちます。

この関数を利用する際は、Libsodium拡張機能がロードされているか、最初に確認することが重要です。鍵は厳重に管理し、ナンスは暗号化ごとに必ず一意な値を使用してください。ナンスの再利用はセキュリティ上の深刻な脆弱性につながります。追加認証データは暗号化時と完全に一致させる必要があり、少しでも異なると復号に失敗します。この関数は復号に失敗した場合 false を返しますので、必ず結果を検証し、適切にエラーハンドリングを行ってください。鍵、ナンス、追加データが全て一致しないと復号できず、これらはデータ改ざんの検知にも利用できます。

関連コンテンツ

関連IT用語

関連プログラミング言語