🌐 言語: 🇻🇳 Tiếng Việt · 🇬🇧 English · 🇯🇵 日本語(現在)
GP247 の機密データの暗号化
ℹ️ 対応バージョン: 保存データの暗号化(at-rest 暗号化)機能(専用鍵
GP247_ENCRYPTION_KEY、コマンドgp247:encryption-key-rotate、castSecret)はgp247/core3.0.3 以降でのみ使えます。それより古いバージョンでは、これらの機密情報は平文で保存されます。バージョンはphp artisan gp247:infoで確認してください。
はじめに
このドキュメントでは、GP247 が機密情報をどのように保護しているか(SMTP パスワード、Google Captcha のシークレット、OAuth クライアントシークレット、プラグインのライセンスなど)を説明します。そして最も重要な点として、組み込みのコマンドを使ってデータを失わずに暗号鍵を安全に変更する手順を説明します。サイト運営者と導入担当者向けです。最後の章は、独自のデータを暗号化したい開発者向けです。読み終えると、どのデータが暗号化されるのか、鍵はどこにあるのか、鍵を正しく変更するにはどうすればよいかがわかります。
at-rest 暗号化とは(簡単に)
「at-rest」とは、データベースに保存されている間、データが暗号化されているという意味です。GP247 は SMTP パスワードを平文で保存する代わりに、enc:v2:… で始まる読めない文字列を保存します。正しい暗号鍵を持つシステムだけが、元に戻して読めます。
守れるもの: データベースのバックアップを入手した人や、テーブルを盗み見た人は、鍵を持っていないため機密情報を読めません。
守れないもの: データベースと鍵の両方を持つ人(サーバーの全権限を持つ人)は読めます。これはデータベースに保存する機密情報の標準的な保護レベルであり、絶対に破られない金庫ではありません。
暗号鍵の場所:GP247_ENCRYPTION_KEY
GP247 は機密情報の暗号化に専用の鍵を使います。.env ファイルの変数 GP247_ENCRYPTION_KEY です。この鍵は、意図的に APP_KEY(Laravel 共通の鍵)から分離されています。そのため、APP_KEY を変更・再生成しても、暗号化済みの機密情報には影響しません。
GP247_ENCRYPTION_KEY をまだ設定していない場合、GP247 は動作を止めないように一時的に APP_KEY を使います。ただし、診断コマンド gp247:doctor が専用鍵を設定するよう通知します。最初から設定しておくことをおすすめします(下の章を参照)。
初めて専用の鍵を設定する(インストール直後に行うことを推奨)
-
プロジェクトのフォルダーで Terminal を開き、次のコマンドで新しい鍵を生成します。
php artisan key:generate --showこのコマンドは
base64:…=形式の鍵を表示するだけで、何も変更しません。表示された値をコピーしてください。 -
.envファイルを開き、GP247_ENCRYPTION_KEY=の行を探して、コピーした鍵を貼り付けます。GP247_ENCRYPTION_KEY=base64:YourNewKey...= -
システムが新しい鍵を読み込むように、設定のキャッシュを削除します。
php artisan config:clear -
.envをバックアップし(鍵が含まれています)、サーバー外の安全な場所に保管します。鍵を失うと、暗号化済みの機密情報を読めなくなります。
専用鍵を設定する前から、
APP_KEYで暗号化された機密情報がサイトにある場合は、専用鍵を設定した後にphp artisan gp247:encryption-key-rotateを実行して、すべてを専用鍵で暗号化し直してください(下の鍵の変更の章を参照。手順はまったく同じです)。
暗号化されるデータ
「機密」として指定された項目は、保存時に自動で暗号化されます。
| データ | 画面 |
|---|---|
SMTP パスワード(smtp_password) |
「サイト設定」→「メール & SMTP」 |
| Google Captcha のシークレットキー | GoogleCaptcha プラグイン |
| OAuth クライアントシークレット(Facebook/Google/GitHub など) | ソーシャルログインプラグイン(LoginSocial) |
| 有料プラグインのライセンス | 拡張機能/ライセンスの管理画面 |
管理者アカウントのパスワードは、ここには含まれません。パスワードは一方向にハッシュ化(bcrypt)されており、元に戻せる暗号化ではありません。
暗号鍵を安全に変更する手順(データを失わずに)
ここが最も重要な部分です。鍵を変更するのは、鍵の漏えいが疑われる場合(誤って .env を Git に上げた など)か、セキュリティポリシーで求められる場合だけにしてください。GP247 には、重い作業を代わりに行うコマンド gp247:encryption-key-rotate があります。このコマンドは、すべての機密情報を古い鍵で読み取り、新しい鍵で暗号化し直します。
⚠️
GP247_ENCRYPTION_KEYを新しい鍵に手で書き換えて終わり、ということは絶対にしないでください。そうすると、古い機密情報がすべて読めなくなります。必ず次の8つの手順に従ってください。
-
作業前にバックアップします。
.envファイルを安全な場所にコピーし(例:.env.backup)、データベースもバックアップします。これが安全網になります。 -
現在の鍵を控えます。
.envを開き、GP247_ENCRYPTION_KEYの値(base64:…=形式)をそのまま別の場所にコピーします。これが古い鍵です。 -
新しい鍵を生成します(まだ適用しません)。 Terminal で次を実行します。
php artisan key:generate --show表示された
base64:…=の値をコピーします。これが新しい鍵です。 -
.envファイルを編集します。 次の2つを行います。- 古い鍵(手順2)を
GP247_ENCRYPTION_PREVIOUS_KEYSの行に入れます。 GP247_ENCRYPTION_KEYを新しい鍵(手順3)に変更します。
結果は次のようになります(実際の値に置き換えてください)。
GP247_ENCRYPTION_KEY=base64:NewKey...= GP247_ENCRYPTION_PREVIOUS_KEYS=base64:OldKey...=GP247_ENCRYPTION_PREVIOUS_KEYSには、カンマ区切りで複数の古い鍵を入れられます。 - 古い鍵(手順2)を
-
設定のキャッシュを削除します。
php artisan config:clear -
鍵の変更コマンドを実行して、すべての機密情報を新しい鍵で暗号化し直します。
php artisan gp247:encryption-key-rotate成功すると、テーブルごとに変換した行数が表示されます。例:
admin_config.value: 5 converted, 0 already current, 0 undecryptable。 「undecryptable」(復号できない)の行がある場合は、手順4の古い鍵が正しくありません。GP247_ENCRYPTION_PREVIOUS_KEYSを確認してから、もう一度実行してください。このコマンドはエラーの行を上書きしないため、データが壊れることはありません。書き込まずに事前確認したい場合は、
php artisan gp247:encryption-key-rotate --dry-runを実行します。 -
診断コマンドで確認します。
php artisan gp247:doctorsecret_decryptableの行を探します。PASS と「N secrets OK」が表示されていれば、すべての機密情報を新しい鍵で読めます。 -
後片付けをします。 手順6ですべての行の変換が報告され(「undecryptable」が0)、
doctorが PASS になったら、.envからGP247_ENCRYPTION_PREVIOUS_KEYSの行を削除し、もう一度php artisan config:clearを実行してかまいません。自信がなければ、そのままにしておいてください。古い鍵を残しても害はありません。
鍵の変更を誤った場合・鍵を失った場合
- 古い鍵がまだ手元にある(
.env.backupにある、または控えてある)場合: それをGP247_ENCRYPTION_PREVIOUS_KEYSに入れ、php artisan config:clearを実行してから、手順6からやり直します。データは読めるようになります。 - 古い鍵がどこにも残っていない場合: 古い機密情報は復元できません。各設定画面で手作業で入力し直す必要があります(SMTP パスワード、シークレット、ライセンスなど)。システムが停止することはありません。機密情報を使う機能(メール送信、決済など)が、入力し直すまで止まるだけです。これが 手順1(バックアップ)が必須である理由です。
開発者向け:独自のデータカラムを暗号化する(設定テーブル以外)
プラグインや機能に、設定テーブル以外で機密情報を保存するカラム(例: 外部サービスのトークン)がある場合は、GP247 の共通 cast で暗号化します。1行だけで済み、core を変更する必要はありません。
// モデル内:
protected $casts = [
'api_token' => \GP247\Core\Casts\Secret::class,
];
これで、PHP 内で $model->api_token を読み書きすると平文として扱われ、データベース内では常に enc:v2:… になります。
gp247:doctor と gp247:encryption-key-rotate がこのカラムも対象にする(確認と鍵の変更)ように、プラグインの Provider.php(プラグインが有効なときのブロック内)で宣言します。
config(['gp247-config.security.encrypted_columns.my_plugin_tokens' => ['api_token']]);
注意点は3つです。(1) 暗号文は長いため、カラムは TEXT 型にしてください。(2) 暗号化したカラムでは検索・絞り込みができません(検索したい場合は、別途「ブラインドインデックス」用のカラムが必要です)。(3) 鍵の変更コマンドが1行ずつ更新できるよう、テーブルには主キーのカラム id が必要です。
条件と制約(操作の前に確認)
- 暗号鍵(
GP247_ENCRYPTION_KEY)と.envファイルは必ずバックアップしてください。 鍵を失うと、暗号化済みのすべての機密情報を読めなくなります。他に復元する方法はありません。 - 鍵を変更する前に、必ず古い鍵を
GP247_ENCRYPTION_PREVIOUS_KEYSに入れてください。 そうしないと、鍵の変更コマンドが古い機密情報を読めません。最も見落としやすい手順です。 - 「鍵を変更する」ために
GP247_ENCRYPTION_KEYを手で書き換えないでください。 必ずgp247:encryption-key-rotateの手順で変更してください。そうしないと、古いデータが読めなくなります。 - 復号に失敗してもサイトは停止しません。 鍵が間違っている場合、機密情報は空として扱われ、関連する機能が一時停止します。真っ白なエラー画面にはなりません(制限のあるホスティングでもサイトを動かし続けるための意図的な設計です)。
- 暗号化されたデータでは検索・絞り込みができません。 保存されている値は読めない文字列なので、
WHERE = 実際の値は使えません。 .envを変更したら、必ずphp artisan config:clearを実行してください。 そうしないと、システムがキャッシュされた古い設定を使い続けることがあります。
よくある質問(Q&A)
Q1: GP247_ENCRYPTION_KEY は必ず設定しなければなりませんか?
→ インストール直後に設定することを強くおすすめします。未設定の場合、GP247 は一時的に APP_KEY を使い、gp247:doctor が通知します。専用鍵を設定しておけば、APP_KEY を変更しても機密情報に影響しません。
Q2: 鍵を変更するには、どのコマンドを使いますか?
→ php artisan gp247:encryption-key-rotate です。すべての機密情報を新しい鍵で暗号化し直します。ただし、「暗号鍵を安全に変更する手順」の章の手順をすべて行ってください(先に古い鍵を GP247_ENCRYPTION_PREVIOUS_KEYS に入れます)。
Q3: gp247:doctor が「secrets undecryptable」と表示します。どういう意味ですか?
→ 復号できない機密情報があるという意味です。通常は、鍵を変更したのに古い鍵を宣言していないことが原因です。古い鍵を GP247_ENCRYPTION_PREVIOUS_KEYS に入れ、php artisan config:clear を実行してから、もう一度 gp247:encryption-key-rotate を実行してください。古い鍵を完全に失った場合は、機密情報を入力し直す必要があります。
Q4: 鍵の変更コマンドは、何度実行しても安全ですか?
→ はい。すでに新しい鍵を使っている行はスキップするため、再実行しても害はありません。書き込まずに事前確認したい場合は --dry-run を付けてください。
Q5: APP_KEY(暗号鍵ではないほう)を変更すると、機密情報は失われますか?
→ 専用の GP247_ENCRYPTION_KEY を設定していれば、失われません。機密情報は専用鍵に結び付いており、APP_KEY には依存しません。
Q6: SMTP パスワードは管理画面で見えてしまいますか?
→ 平文では表示されません。入力欄は ●●● で隠され、データベースには暗号化されて(enc:v2:…)保存されます。
Q7: 自分のプラグインに独自の機密情報カラムがあります。どう暗号化すればよいですか?
→ モデルの $casts で cast \GP247\Core\Casts\Secret::class を使い、doctor/鍵の変更コマンドの対象になるよう、そのカラムを gp247-config.security.encrypted_columns に宣言してください。「開発者向け」の章を参照してください。
Q8: サーバーの権限を持つ人は、機密情報を読めるのですか?
→ はい。データベースと鍵の両方を持つ人は誰でも復号できます。at-rest 暗号化は、バックアップ経由の漏えいや DB の盗み見を防ぐものであり、すでにサーバーの全権限を持つ人を防ぐものではありません。
📅 最終更新: 2026-10-22 · ✍️ 作成者 (Author): GP247