暗号化
イントロダクション
Laravelの暗号化サービスは、AES-256およびAES-128暗号化を使用したOpenSSLを介してテキストを暗号化および復号するための、シンプルで便利なインターフェイスを提供します。Laravelの暗号化された値はすべて、メッセージ認証コード(MAC)を使用して署名されるため、暗号化された後はその基になる値を変更したり、改ざんしたりできません。
設定
Laravelのエンクリプタを使用する前に、config/app.php設定ファイルのkey設定オプションを設定する必要があります。この設定値はAPP_KEY環境変数によって駆動されます。php artisan key:generateコマンドを使用してこの変数の値を生成する必要があります。key:generateコマンドは、PHPの安全なランダムバイトジェネレータを使用して、アプリケーションの暗号学的に安全なキーを構築するためです。通常、APP_KEY環境変数の値は、Laravelのインストール中に生成されます。
暗号化キーの安全なローテーション
アプリケーションの暗号化キーを変更すると、認証済みユーザーセッションはすべてアプリケーションからログアウトされます。これは、セッションクッキーを含むすべてのクッキーがLaravelによって暗号化されているためです。さらに、以前の暗号化キーで暗号化されたデータを復号することができなくなります。
この問題を軽減するために、Laravelでは以前の暗号化キーをアプリケーションのAPP_PREVIOUS_KEYS環境変数にリストアップできます。この変数には、以前のすべての暗号化キーをカンマ区切りのリストで含めることができます。
1APP_KEY="base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY="2APP_PREVIOUS_KEYS="base64:2nLsGFGzyoae2ax3EF2Lyq/hH6QghBGLIq5uL+Gp8/w="
この環境変数を設定すると、Laravelは値を暗号化するときに常に「現在」の暗号化キーを使用します。ただし、値を復号するときは、Laravelは最初に現在のキーを試行し、現在のキーを使用して復号に失敗した場合、Laravelはいずれかのキーで値を復号できるまで、以前のすべてのキーを試します。
この安全な復号へのアプローチにより、暗号化キーがローテーションされても、ユーザーは中断することなくアプリケーションを使い続けられます。
エンクリプタの使用
値の暗号化
Cryptファサードが提供するencryptStringメソッドを使用して値を暗号化できます。すべての暗号化された値は、OpenSSLとAES-256-CBC暗号を使用して暗号化されます。さらに、すべての暗号化された値には、メッセージ認証コード(MAC)で署名されます。統合されたメッセージ認証コードは、悪意のあるユーザーによって改ざんされた値の復号を防ぎます。
1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\RedirectResponse; 6use Illuminate\Http\Request; 7use Illuminate\Support\Facades\Crypt; 8 9class DigitalOceanTokenController extends Controller10{11 /**12 * Store a DigitalOcean API token for the user.13 */14 public function store(Request $request): RedirectResponse15 {16 $request->user()->fill([17 'token' => Crypt::encryptString($request->token),18 ])->save();19 20 return redirect('/secrets');21 }22}
値の復号
Cryptファサードが提供するdecryptStringメソッドを使用して値を復号できます。メッセージ認証コードが無効である場合など、値を正しく復号できない場合は、Illuminate\Contracts\Encryption\DecryptExceptionが投げられます。
1use Illuminate\Contracts\Encryption\DecryptException;2use Illuminate\Support\Facades\Crypt;3 4try {5 $decrypted = Crypt::decryptString($encryptedValue);6} catch (DecryptException $e) {7 // ...8}