コンテンツにスキップ

暗号化

はじめに

Laravelの暗号化サービスは、AES-256およびAES-128暗号化を使用して、OpenSSLを介したテキストの暗号化と復号化を行うためのシンプルで便利なインターフェースを提供します。 Laravelのすべての暗号化された値は、メッセージ認証コード(MAC)を使用して署名されているため、暗号化されると基になる値を変更または改ざんすることはできません。

設定

Laravelの暗号化機能を使用する前に、`config/app.php`設定ファイルの`key`設定オプションを設定する必要があります。 この設定値は、`APP_KEY`環境変数によって決まります。 `key:generate`コマンドは、PHPの安全なランダムバイトジェネレータを使用して、アプリケーションの暗号化的に安全な鍵を構築するため、この変数の値を生成するには、`php artisan key:generate`コマンドを使用する必要があります。 通常、`APP_KEY`環境変数の値は、Laravelのインストール中に自動的に生成されます。

暗号鍵のグレースフルローテーション

アプリケーションの暗号化キーを変更すると、認証されたすべてのユーザーセッションがアプリケーションからログアウトされます。 これは、セッションCookieを含むすべてのCookieがLaravelによって暗号化されているためです。 また、以前の暗号化キーで暗号化されたデータを復号化できなくなります。

この問題を軽減するために、Laravelでは、アプリケーションの`APP_PREVIOUS_KEYS`環境変数に以前の暗号化キーをリストすることができます。 この変数には、以前のすべての暗号化キーをカンマ区切りでリストすることができます。

APP_KEY="base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY="
APP_PREVIOUS_KEYS="base64:2nLsGFGzyoae2ax3EF2Lyq/hH6QghBGLIq5uL+Gp8/w="

この環境変数を設定すると、Laravelは値を暗号化するときに常に「現在」の暗号化キーを使用します。 ただし、値を復号化するときに、Laravelは最初に現在のキーを試行し、現在のキーを使用して復号化に失敗した場合、Laravelはキーのいずれかが値を復号化できるまで、すべての以前のキーを試行します。

グレースフル復号化のこのアプローチにより、暗号化キーがローテーションされても、ユーザーはアプリケーションを中断することなく使い続けることができます。

暗号化機能の使い方

値の暗号化

`Crypt`ファサードによって提供される`encryptString`メソッドを使用して、値を暗号化できます。 すべての暗号化された値は、OpenSSLおよびAES-256-CBC暗号を使用して暗号化されます。 さらに、すべての暗号化された値は、メッセージ認証コード(MAC)で署名されます。 統合されたメッセージ認証コードは、悪意のあるユーザーによって改ざんされた値の復号化を防ぎます。

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
 
class DigitalOceanTokenController extends Controller
{
/**
* Store a DigitalOcean API token for the user.
*/
public function store(Request $request): RedirectResponse
{
$request->user()->fill([
'token' => Crypt::encryptString($request->token),
])->save();
 
return redirect('/secrets');
}
}

値の復号化

`Crypt`ファサードによって提供される`decryptString`メソッドを使用して、値を復号化できます。 メッセージ認証コードが無効な場合など、値を正しく復号化できない場合は、`Illuminate\Contracts\Encryption\DecryptException`がスローされます。

use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;
 
try {
$decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
// ...
}