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

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

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

作成日: 更新日:

基本的な使い方

sodium_crypto_aead_aes256gcm_encrypt関数は、Advanced Encryption Standard (AES) の256ビット鍵長とGalois/Counter Mode (GCM) を組み合わせた方式を用いて、データを安全に暗号化する処理を実行する関数です。この関数は、データの機密性(内容が第三者に漏れないこと)、完全性(データが途中で改ざんされていないこと)、そして認証(データが正規の送信元から送られたものであること)という3つのセキュリティ要素を同時に保証する、認証付き暗号化(AEAD: Authenticated Encryption with Associated Data)を提供します。

この関数を使用する際は、暗号化したいメッセージ(平文)と、秘密鍵、そして「ワンタイムナンス(Nonce)」と呼ばれる各暗号化処理ごとに異なる一意の値が必要です。Nonceは、同じ鍵で複数のデータを暗号化する際に、セキュリティ上の脆弱性を避けるために非常に重要な役割を果たし、決して再利用してはなりません。また、暗号化はされませんが、その改ざんを検知したい追加データ($additional_data)も指定できます。これは、通信のヘッダー情報など、公開されても問題ないが、その整合性を保証したい場合に有効です。

処理が成功すると、暗号化されたデータと認証タグが結合された文字列が返されます。返されたデータは、対応する復号化関数でしか元に戻すことができません。データの安全性を確保するためには、秘密鍵の厳重な管理と、Nonceの適切な生成・使用が不可欠です。

構文(syntax)

1<?php
2$encrypted_data_string = sodium_crypto_aead_aes256gcm_encrypt(
3    $message_to_encrypt_string,
4    $additional_authenticated_data_string,
5    $unique_nonce_string,
6    $encryption_key_string
7);

引数(parameters)

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

  • string $message: 暗号化したい平文データを指定する文字列
  • string $additional_data: 認証のみを行う追加データを指定する文字列
  • string $nonce: 一度しか使用できないランダムな値を指定する文字列
  • string $key: データの暗号化と復号に使用する鍵を指定する文字列

戻り値(return)

string|false

暗号化されたデータと認証タグを連結した文字列、または失敗した場合は false を返します。

サンプルコード

PHP: sodium_crypto_aead_aes256gcm_encrypt example

1<?php
2
3/**
4 * メッセージを指定された鍵とNonceを使ってAES256-GCMで暗号化します。
5 *
6 * この関数は、libhydrogenまたはlibsodiumライブラリが利用可能であることを前提としています。
7 * Nonce(Number used once)は各暗号化操作で一意である必要があり、
8 * この関数内で安全に生成されます。
9 *
10 * @param string $message         暗号化する元のメッセージ。
11 * @param string $additionalData  認証のみに使用される追加データ(暗号化はされない)。
12 * @param string $key             暗号化に使用する秘密鍵(SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTESバイト長)。
13 *                                この鍵は事前に安全な方法で生成されている必要があります。
14 * @return array{ciphertext: string, nonce: string}|false 暗号化されたデータ(暗号文とNonce)または失敗時はfalse。
15 * @throws InvalidArgumentException 鍵の長さが不正な場合。
16 * @throws Exception Nonceの生成に失敗した場合。
17 */
18function encryptMessageAes256Gcm(string $message, string $additionalData, string $key): array|false
19{
20    // 非公開の鍵の長さが正しいか検証します。
21    // SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTESは、AES256-GCMに必要な鍵の長さ(32バイト)を定義します。
22    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES) {
23        throw new InvalidArgumentException(
24            sprintf(
25                '鍵の長さが不正です。%dバイトである必要がありますが、%dバイトが与えられました。',
26                SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES,
27                mb_strlen($key, '8bit')
28            )
29        );
30    }
31
32    // Nonce(ナンバー・ユーズド・ワンス)は各暗号化操作で一意である必要があります。
33    // SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES は Nonce の推奨サイズ(12バイト)を定義しています。
34    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
35    if ($nonce === false) {
36        // random_bytesが失敗することは稀ですが、念のためエラーをスローします。
37        throw new Exception('Nonceの生成に失敗しました。');
38    }
39
40    // sodium_crypto_aead_aes256gcm_encrypt を使用してメッセージを暗号化します。
41    // 戻り値は認証タグを含む暗号文です。
42    $ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
43        $message,
44        $additionalData,
45        $nonce, // 関数内で生成された一意のNonce
46        $key    // 提供された秘密鍵
47    );
48
49    if ($ciphertext === false) {
50        // 暗号化に失敗した場合、falseを返します。
51        return false;
52    }
53
54    // 復号のために、暗号文と一緒にNonceも保存・送信する必要があります。
55    // Nonceは秘密にする必要はありませんが、改ざんされてはなりません。
56    return [
57        'ciphertext' => $ciphertext,
58        'nonce'      => $nonce,
59    ];
60}
61
62// --- 以下は encryptMessageAes256Gcm 関数の使用例です ---
63
64// 暗号化に使用する秘密鍵を生成します。
65// この鍵は、暗号化と復号の両方で使用されるため、安全に保管する必要があります。
66try {
67    $encryptionKey = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES);
68    if ($encryptionKey === false) {
69        throw new Exception('鍵の生成に失敗しました。');
70    }
71} catch (Exception $e) {
72    // 実際のアプリケーションでは、エラーログ記録や適切なエラーハンドリングが必要です。
73    error_log('致命的なエラー: 秘密鍵の生成に失敗しました: ' . $e->getMessage());
74    exit(1); // 処理を終了
75}
76
77$originalMessage  = 'これはAES256-GCMで暗号化される秘密のメッセージです。';
78$additionalData   = 'これは認証のみに使用される追加データです。'; // 暗号化はされないが、認証の際に利用されます。
79
80// メッセージを暗号化します。
81try {
82    $encryptedResult = encryptMessageAes256Gcm($originalMessage, $additionalData, $encryptionKey);
83
84    if ($encryptedResult === false) {
85        // 暗号化失敗時の処理。
86        error_log('メッセージの暗号化に失敗しました。');
87        $encryptedCiphertext = null;
88        $encryptedNonce      = null;
89    } else {
90        $encryptedCiphertext = $encryptedResult['ciphertext'];
91        $encryptedNonce      = $encryptedResult['nonce'];
92
93        // $encryptedCiphertext と $encryptedNonce は、復号のために安全に保存または転送されるべきデータです。
94        // 例: データベースに保存したり、ネットワーク経由で送信したりします。
95        // このサンプルでは、変数に格納されるだけで、標準出力には何も表示されません。
96
97        // --- 復号処理のヒント ---
98        // 復号には sodium_crypto_aead_aes256gcm_decrypt 関数を使用します。
99        // その際、この暗号文 ($encryptedCiphertext)、Nonce ($encryptedNonce)、
100        // 追加データ ($additionalData)、そして同じ秘密鍵 ($encryptionKey) が必要になります。
101        //
102        // $decryptedMessage = sodium_crypto_aead_aes256gcm_decrypt(
103        //     $encryptedCiphertext,
104        //     $additionalData,
105        //     $encryptedNonce,
106        //     $encryptionKey
107        // );
108        //
109        // if ($decryptedMessage !== false) {
110        //     // 復号成功: $decryptedMessage が元のメッセージと一致します。
111        // } else {
112        //     // 復号失敗: データが改ざんされたか、鍵やNonceが間違っている可能性があります。
113        // }
114    }
115} catch (InvalidArgumentException $e) {
116    error_log('引数エラー: ' . $e->getMessage());
117    $encryptedCiphertext = null;
118    $encryptedNonce      = null;
119} catch (Exception $e) {
120    error_log('暗号化処理中に予期せぬエラーが発生しました: ' . $e->getMessage());
121    $encryptedCiphertext = null;
122    $encryptedNonce      = null;
123}

このPHPのサンプルコードは、sodium_crypto_aead_aes256gcm_encrypt関数を用いて、メッセージをAES256-GCM方式で安全に暗号化する方法を示しています。この関数は、libhydrogenまたはlibsodiumライブラリが提供する堅牢な暗号化機能を利用します。

暗号化を行うには、元のメッセージ($message)、認証にのみ使用される追加データ($additional_data)、秘密鍵($key)、そして各暗号化操作で一意である必要があるナンバー・ユーズド・ワンス(Nonce)($nonce)が必要です。サンプルコードでは、セキュリティのベストプラクティスに従い、鍵は事前に安全に生成され、Nonceはrandom_bytes関数を使って自動生成されるように設計されています。これにより、暗号化のたびに異なるNonceが使われ、高いセキュリティを保つことができます。

sodium_crypto_aead_aes256gcm_encrypt関数は、これらすべての引数を受け取り、暗号化されたメッセージ(暗号文)を返します。戻り値は、認証タグを含む暗号文です。サンプルコードのラッパー関数では、暗号文とその暗号化に使用されたNonceをペアにした配列を返しています。復号する際には、この暗号文とNonce、追加データ、そして同じ秘密鍵がすべて必要となります。もし暗号化処理が何らかの理由で失敗した場合は、falseが返され、開発者はエラーを適切に処理できます。

この暗号化関数を利用する際は、いくつかの重要な点に注意が必要です。まず、暗号化に使う「鍵」は32バイト固定長で、random_bytesのような安全な方法で生成し、誰にも知られないよう厳重に保管してください。暗号化と復号で全く同じ鍵を使う必要があります。次に「Nonce(ノンス)」は12バイトで、暗号化のたびに必ず異なる値を生成します。Nonceは暗号文と一緒に保存し、復号時にも必要ですが、秘密にする必要はなく、改ざんされてはいけません。「追加データ」は暗号化されませんが、データの認証に利用されるため、復号時にも同じものが必要です。関数が失敗した場合はfalseを返しますので、必ず戻り値をチェックしてエラーハンドリングを行ってください。本機能はPHPのSodium拡張機能が必要です。

sodium_crypto_aead_aes256gcm_encryptで暗号化する

1<?php
2
3/**
4 * Demonstrates symmetric encryption and decryption using AES-256-GCM with the libsodium extension.
5 *
6 * This function encrypts a message using `sodium_crypto_aead_aes256gcm_encrypt`
7 * and then decrypts it using `sodium_crypto_aead_aes256gcm_decrypt`.
8 * It highlights the use of a key, a nonce, and additional authenticated data (AAD).
9 * For this code to run, the 'sodium' extension must be enabled in PHP.
10 */
11function demonstrateSodiumAes256GcmEncryption(): void
12{
13    // 1. Generate a secure random key for AES-256-GCM.
14    // This key must be kept secret and shared only between parties who need to encrypt/decrypt.
15    $key = sodium_crypto_aead_aes256gcm_keygen();
16
17    // 2. Define the plaintext message to be encrypted.
18    $message = 'This is a sensitive message that needs to be securely transmitted.';
19
20    // 3. Define additional authenticated data (AAD).
21    // This data is NOT encrypted but is authenticated along with the ciphertext.
22    // If it's tampered with during transit, decryption will fail, protecting data integrity.
23    $additionalData = 'metadata_identifier_123';
24
25    // 4. Generate a unique nonce (Number Used Once).
26    // A nonce *must never* be reused with the same key for encryption.
27    // The required nonce length for AES-256-GCM is fixed at 12 bytes.
28    $nonce = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NONCEBYTES);
29
30    echo "Original Message: " . $message . "\n";
31    echo "Additional Authenticated Data: " . $additionalData . "\n";
32    echo "Key (Base64 encoded): " . base64_encode($key) . "\n";
33    echo "Nonce (Base64 encoded): " . base64_encode($nonce) . "\n\n";
34
35    // 5. Encrypt the message.
36    // The function returns the ciphertext on success, or false on failure.
37    $ciphertext = sodium_crypto_aead_aes256gcm_encrypt(
38        $message,
39        $additionalData,
40        $nonce,
41        $key
42    );
43
44    if ($ciphertext === false) {
45        echo "ERROR: Encryption failed!\n";
46        return;
47    }
48
49    echo "Encryption successful!\n";
50    // For display and storage, binary data like ciphertext is often base64 encoded.
51    echo "Ciphertext (Base64 encoded): " . base64_encode($ciphertext) . "\n\n";
52
53    // --- Decryption Phase ---
54    echo "Attempting to decrypt the message using the same key, nonce, and AAD...\n";
55
56    // 6. Decrypt the ciphertext.
57    // All original parameters (ciphertext, AAD, nonce, key) must be provided correctly.
58    // If the ciphertext, AAD, or key is altered, decryption will fail (return false).
59    $decryptedMessage = sodium_crypto_aead_aes256gcm_decrypt(
60        $ciphertext,
61        $additionalData,
62        $nonce,
63        $key
64    );
65
66    if ($decryptedMessage === false) {
67        echo "ERROR: Decryption failed or data was tampered with!\n";
68        return;
69    }
70
71    echo "Decryption successful!\n";
72    echo "Decrypted Message: " . $decryptedMessage . "\n\n";
73
74    // 7. Verify that the decrypted message matches the original.
75    if ($message === $decryptedMessage) {
76        echo "Verification: The original and decrypted messages match.\n";
77    } else {
78        echo "Verification: ERROR! The original and decrypted messages DO NOT match.\n";
79    }
80}
81
82// Execute the demonstration function.
83demonstrateSodiumAes256GcmEncryption();
84
85?>

PHPのsodium_crypto_aead_aes256gcm_encrypt関数は、sodium拡張機能を用いてAES-256-GCMという安全性の高いアルゴリズムでデータを暗号化します。この関数は、データを秘密にするだけでなく、そのデータが送信中に改ざんされていないかを検出する認証機能も提供している点が特徴です。

引数として、暗号化したい元の文字列である$message、暗号化はされませんが改ざんチェックの対象となる$additional_data(追加認証データ)、毎回異なる値を生成する必要がある$nonce(ノンス)、そして暗号化と復号化の両方に使用される秘密の$keyを指定します。これらの引数はすべて文字列型で渡されます。戻り値は、暗号化に成功した場合は暗号化された文字列が返され、失敗した場合はfalseが返されます。

サンプルコードでは、まずsodium_crypto_aead_aes256gcm_keygen()で安全な秘密鍵を生成し、random_bytes()SODIUM_CRYPTO_AEAD_AES256GCM_NONCEBYTESを使ってノンスを準備しています。これらと指定のメッセージ、追加認証データを用いてsodium_crypto_aead_aes256gcm_encrypt関数でメッセージを暗号化します。その後、同じ鍵、ノンス、追加認証データを使ってsodium_crypto_aead_aes256gcm_decrypt関数で元のメッセージに復号化する一連の流れが示されています。セキュリティを確保するため、$keyは厳重に管理し、$nonceは同じ鍵で複数回暗号化する際に決して再利用してはならない点に十分注意が必要です。この関数を利用するには、PHPにsodium拡張機能が有効になっている必要があります。

sodium_crypto_aead_aes256gcm_encrypt関数では、ナンス(Nonce)の適切な管理が極めて重要です。同じ鍵での使い回しは厳禁。必ず暗号ごとにユニークな値を生成し、暗号文と共に保管・伝送してください。鍵は秘密に厳重に管理し、外部に漏らさないことが絶対条件です。追加認証データは暗号化されませんが、改ざん検知のため復号時も同値が必要です。関数は失敗時falseを返すため、戻り値確認とエラー処理を必ず行いましょう。本機能はPHPのSodiumエクステンションが必須です。

関連コンテンツ

関連IT用語

関連プログラミング言語