メインコンテンツまでスキップ

暗号化

はじめに

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

構成

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

優雅な暗号鍵のローテーション

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

この問題を緩和するために、Laravel では、アプリケーションの APP_PREVIOUS_KEYS 環境変数に以前の暗号鍵をリストアップすることができます。 この変数には、すべての以前の暗号鍵のコンマ区切りリストが含まれる可能性があります:

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

この環境変数を設定すると、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) {
// ...
}