【PHP8.x】SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES定数の使い方
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES定数は、PHPのSodium拡張機能によって提供される、セキュアな認証付き暗号化アルゴリズムである「ChaCha20-Poly1305(IETF標準バージョン)」で使用される「ナンス(nonce)」の推奨バイト数を表す定数です。ナンスとは、"number used once" の略で、暗号化処理を行う際に、同じ暗号鍵と平文を使っても常に異なる暗号文を生成するために一度だけ使用される、予測不可能なランダムな値のことです。これにより、攻撃者が過去の暗号文から情報の一部を推測しにくくする効果があり、暗号のセキュリティを飛躍的に向上させる重要な要素となります。
この定数は、開発者がChaCha20-Poly1305(IETF)アルゴリズムを用いてデータを安全に暗号化する際に、ナンスとしてどのくらいの長さのバイト列を用意すべきかを明確に示します。具体的には、このアルゴリズムでは12バイトのナンスが標準で定められており、この定数の値もその12を示しています。プログラマーは、ナンスを生成する処理や、暗号化関数にナンスの長さを指定する際に、この定数を利用することで、常に正しい長さのナンスを適用でき、意図しないセキュリティ上の脆弱性を防ぎながら、堅牢なアプリケーションを構築することができます。
構文(syntax)
1<?php 2 3echo SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES; 4 5?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
この定数は、ChaCha20-Poly1305 IETFモードでAEAD暗号化を行う際に、計算に必要な秘密鍵のバイト数を整数で返します。
サンプルコード
PHP libsodiumでChaCha20-Poly1305 IETF認証付き暗号化する
1<?php 2 3/** 4 * ChaCha20-Poly1305 IETFモードを使用したデータの暗号化と復号化のサンプル。 5 * 6 * 【重要なお知らせ】 7 * リファレンス情報で指定された定数 `SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES` は、 8 * PHP 8 の `libsodium` 拡張には存在しません。 9 * 10 * そのため、本サンプルコードではキーワードとして指定された `sodium_crypto_aead_chacha20poly1305_ietf_npubbytes` 11 * に最も関連性の高い、実際に存在する定数 `SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES` (ナンスのバイト数) を使用し、 12 * ChaCha20-Poly1305 IETF AEAD (認証付き暗号) の基本的な使い方を示します。 13 * 14 * ナンス(Nonce: Number used once)とは、暗号化処理において同じ鍵で複数のメッセージを暗号化する場合でも、 15 * 各メッセージで必ず一度だけ使用される乱数です。これにより、各メッセージの暗号文が異なることが保証され、 16 * 攻撃者が暗号化のパターンを分析することを防ぎます。 17 * 18 * @param string $message 暗号化する平文メッセージ 19 * @param string $additionalData 認証のみを行う追加データ (AAD: Additional Authenticated Data)。 20 * 暗号化はされないが、復号時に内容が一致しないと認証エラーとなる。 21 * @return array|false 成功した場合は暗号化されたデータと復号化されたメッセージの配列、失敗した場合はfalse 22 */ 23function encryptAndDecryptWithChaCha20Poly1305Ietf(string $message, string $additionalData = ''): array|false 24{ 25 // libsodium拡張がロードされているかを確認 26 if (!extension_loaded('sodium')) { 27 echo "エラー: PHP libsodium 拡張がロードされていません。インストールと有効化が必要です。\n"; 28 return false; 29 } 30 31 // ChaCha20-Poly1305 IETFモードに必要なバイト数を取得 32 33 // 鍵のバイト数を取得 34 $keyBytes = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES; 35 echo "ChaCha20-Poly1305 IETF 鍵のバイト数: " . $keyBytes . " バイト\n"; 36 37 // ナンス(Nonce)のバイト数を取得 38 // これはキーワードに関連する「公開番号のバイト数」を示す定数です。 39 $nonceBytes = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES; 40 echo "ChaCha20-Poly1305 IETF ナンスのバイト数: " . $nonceBytes . " バイト\n"; 41 42 // 秘密鍵を生成 (crypto_aead_chacha20poly1305_ietf_keygen() を使用すると適切な長さの鍵が生成されます) 43 $key = sodium_crypto_aead_chacha20poly1305_ietf_keygen(); 44 echo "秘密鍵を生成しました。\n"; 45 46 // ナンスを生成 (セキュアな乱数)。ナンスは各暗号化操作ごとに必ずユニークでなければなりません。 47 $nonce = random_bytes($nonceBytes); 48 echo "ナンスを生成しました。\n"; 49 50 // --- メッセージの暗号化 --- 51 echo "\n--- 暗号化処理 --- \n"; 52 echo "元のメッセージ: " . $message . "\n"; 53 echo "追加認証データ (AAD): " . (empty($additionalData) ? "(なし)" : $additionalData) . "\n"; 54 55 $ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt( 56 $message, // 暗号化する平文 57 $additionalData, // 認証のみ行う追加データ (AAD) 58 $nonce, // ナンス 59 $key // 秘密鍵 60 ); 61 echo "暗号文 (Base64エンコード): " . base64_encode($ciphertext) . "\n"; 62 63 // --- メッセージの復号化 --- 64 echo "\n--- 復号化処理 --- \n"; 65 // 復号化には、元の鍵、ナンス、そして同じ追加データが必要です。 66 // 一つでも異なると復号に失敗します (認証エラー)。 67 $decryptedMessage = sodium_crypto_aead_chacha20poly1305_ietf_decrypt( 68 $ciphertext, // 暗号文 69 $additionalData, // 暗号化時と同じ追加データ 70 $nonce, // 暗号化時と同じナンス 71 $key // 暗号化時と同じ秘密鍵 72 ); 73 74 if ($decryptedMessage === false) { 75 echo "復号化に失敗しました。データが改ざんされたか、鍵/ナンス/追加データが一致しません。\n"; 76 return false; 77 } else { 78 echo "復号化されたメッセージ: " . $decryptedMessage . "\n"; 79 return [ 80 'original_message' => $message, 81 'encrypted_data' => $ciphertext, 82 'decrypted_message' => $decryptedMessage, 83 ]; 84 } 85} 86 87// --- サンプル使用例 --- 88$originalText = "これは、誰にも読まれてはならない非常に機密性の高い情報です。"; 89$contextIdentifier = "document_id:12345-secret-project"; // 関連付けられた追加データ (AAD) 90 91// 暗号化と復号化を実行 92$encryptionResult = encryptAndDecryptWithChaCha20Poly1305Ietf($originalText, $contextIdentifier); 93 94if ($encryptionResult) { 95 echo "\n--- 検証 --- \n"; 96 if ($encryptionResult['original_message'] === $encryptionResult['decrypted_message']) { 97 echo "✅ 暗号化・復号化のサイクルが正常に完了し、元のメッセージと一致しました。\n"; 98 } else { 99 echo "❌ エラー: 復号化されたメッセージが元のメッセージと一致しませんでした。\n"; 100 } 101} 102
このサンプルコードは、PHP 8で提供されるlibsodium拡張を使って、ChaCha20-Poly1305 IETFモードという認証付き暗号方式でデータを安全に暗号化し、その後復号化する一連の流れを示しています。リファレンス情報で指定された定数SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTESはPHPのlibsodium拡張には存在しませんが、代わりにキーワードに関連するSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTESを使用しています。この定数は、暗号化処理に不可欠な「ナンス(Nonce: Number used once)」と呼ばれる、一度だけ使う乱数の推奨バイト数を示しています。ナンスは毎回異なる値を生成することが非常に重要です。
encryptAndDecryptWithChaCha20Poly1305Ietf関数は、$message(暗号化する元の平文)と$additionalData(認証のみを行う追加データ)を受け取ります。この追加データは暗号化されませんが、復号時に内容が一致しないと認証エラーとなり、データの改ざんを検知する役割があります。関数内部ではまずlibsodium拡張がロードされているかを確認し、sodium_crypto_aead_chacha20poly1305_ietf_keygen()で秘密鍵を、random_bytes()とSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTESで適切な長さのユニークなナンスを生成します。
次に、sodium_crypto_aead_chacha20poly1305_ietf_encrypt関数により、メッセージ、追加データ、ナンス、鍵を使って暗号文を生成します。復号化の際には、sodium_crypto_aead_chacha20poly1305_ietf_decrypt関数に同じ暗号文、追加データ、ナンス、鍵を渡します。もしこれらの情報が一つでも異なったり、暗号文が改ざんされていたりすると、復号化は失敗してfalseが返され、安全性が保たれます。成功した場合は復号された平文が返され、関数は元のメッセージ、暗号化されたデータ、復号されたメッセージを含む配列を返します。失敗時にはfalseを返します。
リファレンス情報に記載された定数 SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES は、PHP 8のlibsodium拡張には存在しません。サンプルコードでは関連性の高い SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES(ナンスのバイト数)を使用しており、この点に特に注意が必要です。この暗号化機能を利用するためには、PHP libsodium拡張がインストールされ、有効になっている必要があります。また、ナンスは暗号化操作ごとにrandom_bytes()で必ずユニークな値を生成してください。同じ鍵で複数のデータを暗号化する際にナンスが重複すると、セキュリティが著しく低下します。暗号化と復号化には、同じ秘密鍵、ナンス、そして追加認証データ(AAD)を完全に一致させる必要があります。これらが一つでも異なると、データが改ざんされたと判断され復号に失敗しますので、戻り値がfalseの場合の適切なエラー処理を心がけてください。
sodium_crypto_box による公開鍵暗号処理
1<?php 2 3/** 4 * libsodium を使った公開鍵暗号 (sodium_crypto_box) のサンプル関数 5 * 6 * システムエンジニアを目指す初心者向けに、公開鍵暗号の基本的な流れと、 7 * ノンスのバイト長に関する定数の違いを説明します。 8 * 9 * @return void 10 */ 11function demonstrateSodiumCryptoBox(): void 12{ 13 // libsodium 拡張がロードされているか確認 14 if (!extension_loaded('sodium')) { 15 echo "エラー: libsodium 拡張がロードされていません。\n"; 16 return; 17 } 18 19 // ------------------------------------------------------------------ 20 // ステップ1: キーペアの生成 21 // 送信者(アリス)と受信者(ボブ)のキーペアを生成します。 22 // キーペアは公開鍵と秘密鍵の組み合わせです。 23 // ------------------------------------------------------------------ 24 $aliceKeyPair = sodium_crypto_box_keypair(); 25 $alicePublicKey = sodium_crypto_box_publickey($aliceKeyPair); 26 $aliceSecretKey = sodium_crypto_box_secretkey($aliceKeyPair); 27 28 $bobKeyPair = sodium_crypto_box_keypair(); 29 $bobPublicKey = sodium_crypto_box_publickey($bobKeyPair); 30 $bobSecretKey = sodium_crypto_box_secretkey($bobKeyPair); 31 32 // ------------------------------------------------------------------ 33 // ステップ2: メッセージの暗号化 (アリス -> ボブ) 34 // アリスがボブの公開鍵を使ってメッセージを暗号化します。 35 // ノンス(Nonce: Number used once)は、毎回異なる暗号文を生成するために使用される一意の値です。 36 // 同じ鍵と平文でもノンスが異なれば、異なる暗号文になります。 37 // ------------------------------------------------------------------ 38 $message = 'Hello, secure world from Alice!'; 39 40 // sodium_crypto_box に必要なノンスのバイト長を取得 41 // SODIUM_CRYPTO_BOX_NONCEBYTES は、sodium_crypto_box 用のノンスの推奨バイト長です。 42 $boxNonceBytes = SODIUM_CRYPTO_BOX_NONCEBYTES; 43 44 // リファレンス情報で指定された定数: SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES 45 // この定数は、crypto_aead_chacha20poly1305_ietf という別のAEAD暗号方式で 46 // 使用されるノンスのバイト長 (通常は12バイト) を示します。 47 // sodium_crypto_box では直接使用されませんが、ノンスの概念を理解する上で参考になります。 48 $aeadIetfNonceBytes = SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES; 49 50 // ノンスを安全に生成 51 $nonce = random_bytes($boxNonceBytes); 52 53 // 暗号化 54 $encryptedMessage = sodium_crypto_box( 55 $message, 56 $nonce, 57 $bobPublicKey, // 受信者(ボブ)の公開鍵 58 $aliceSecretKey // 送信者(アリス)の秘密鍵 59 ); 60 61 echo "=== 公開鍵暗号のデモンストレーション ===\n"; 62 echo "元のメッセージ: " . $message . "\n"; 63 echo "sodium_crypto_box のノンス長: " . $boxNonceBytes . " バイト\n"; 64 echo "SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES の値: " . $aeadIetfNonceBytes . " バイト\n"; 65 echo "暗号化されたメッセージ (Base64エンコード): " . base64_encode($encryptedMessage) . "\n\n"; 66 67 // ------------------------------------------------------------------ 68 // ステップ3: メッセージの復号化 (ボブ -> アリス) 69 // ボブは自分の秘密鍵とアリスの公開鍵を使ってメッセージを復号化します。 70 // 暗号化時と同じノンスが必要です。 71 // ------------------------------------------------------------------ 72 $decryptedMessage = sodium_crypto_box_open( 73 $encryptedMessage, 74 $nonce, 75 $alicePublicKey, // 送信者(アリス)の公開鍵 76 $bobSecretKey // 受信者(ボブ)の秘密鍵 77 ); 78 79 if ($decryptedMessage === false) { 80 echo "エラー: メッセージの復号化に失敗しました。\n"; 81 return; 82 } 83 84 echo "復号化されたメッセージ: " . $decryptedMessage . "\n"; 85 86 // 元のメッセージと復号化されたメッセージが一致するか確認 87 if ($message === $decryptedMessage) { 88 echo "結果: メッセージは正しく暗号化され、復号化されました。成功!\n"; 89 } else { 90 echo "結果: メッセージが一致しません。失敗!\n"; 91 } 92} 93 94// デモンストレーション関数を実行 95demonstrateSodiumCryptoBox();
SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTESは、PHP 8で利用できる定数で、認証付き暗号方式の一つであるChaCha20-Poly1305 IETFバージョンで必要とされる、ノンスのバイト長を示す整数(int)型の値です。ノンスとは、暗号化処理において「一度だけ使用される数値」を意味し、同じ鍵と平文であっても常に異なる暗号文を生成するために不可欠です。これにより、暗号文の繰り返し攻撃を防ぎ、セキュリティを強化する役割があります。
この定数は、提供されたサンプルコードで使われているsodium_crypto_box関数が直接使用するものではありません。sodium_crypto_boxが要求するノンスのバイト長は、SODIUM_CRYPTO_BOX_NONCEBYTESという別の定数で定義されています。しかし、SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTESの値は、様々な暗号方式によってノンスの長さが異なることを理解するのに役立ちます。サンプルコードのように、メッセージの暗号化や復号化には適切な長さのノンスが必要とされ、そのノンスは安全に生成し、重複しないように管理することがセキュリティ上極めて重要です。
sodium_crypto_box関数では、SODIUM_CRYPTO_BOX_NONCEBYTESが正しいノンスのバイト長を示します。リファレンスにあるSODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTESは別のAEAD暗号方式のノンス長であり、混同しないよう注意が必要です。ノンスはセキュリティ上非常に重要で、random_bytes()関数でメッセージごとに毎回異なる値を生成し、絶対に使い回さないでください。また、秘密鍵は決して公開せず、厳重に管理することが必須です。コード実行前にsodium拡張が有効か確認し、復号失敗時に備えて適切にエラーを処理してください。