laravelを使用してlogを暗号化した後、復元したlogをtxtファイルでダウンロードする方法について

実現したいこと

ユーザーが入力したフォームの内容を暗号化した状態でlogファイルに保存。
さらに、暗号化したlogは、復元した状態でtxtファイルとしてダウンロードできるようにしたい。

※現状、暗号化していないlogデータであれば、上記の処理は実現できているのですが、暗号化したデータを復元しようとするとエラーが表示されてしまいます。。。

前提

laravel(バージョン10)
php 8.1

現状出来ている事
① ユーザーが入力した情報はバリデーションを行い、「/storege/logs/form.log」というファイル名で保存
② LogController.phpというファイルを作成して、「https://ドメイン/log/」 というアドレスにアクセスしたら、form.logの内容を「formlog.txt」といった形式でダウンロード。

発生している問題・エラーメッセージ

上記①でバリデーション済データ(配列)をlogに書き込む際に、
「Crypt::encrypt(バリデーション済データ)」といった形で、
暗号化してlogに記載し、
LogController.phpにて「/storege/logs/form.log」ファイルを取得して、
Crypt::decrypt(取得したlogファイル)を行うと下記のエラーが表示されてしまいます。。。

Illuminate\Contracts\Encryption\DecryptException The payload is invalid.

該当のソースコード

各コントローラーファイルから抜粋

#IndexController.php →バリデーション済データを暗号化してlogに保存 ▼postの処理 public function confirm(Request $request, InputFormRequest $formrRequest) { //バリデーション済データ $validated = $formrRequest->validated(); // 暗号化 $encryptedData = Crypt::encrypt($validated); // ログの書込み Log::channel('daily')->debug($encryptedData); }
#UserLogController.php →暗号化されたlogファイルを取得して復元&データ取得 ▼getの処理 public function index(Request $request) { // ログファイルの取得 $getLogFilePath = storage_path('logs/form.log'); // ログファイルが存在するか確認 if (File::exists($getLogFilePath)) { // ログファイルの内容を取得 $logContent = File::get($getLogFilePath); // ログファイルの復元 $decryptedData = Crypt::decrypt($logContent); // ダウンロード用の一時ファイルを作成 $tempFilePath = tempnam(sys_get_temp_dir(), 'laravel_log_'); File::put($tempFilePath, $decryptedData); // レスポンスを生成してファイルをダウンロード return response()->stream( function () use ($tempFilePath) { readfile($tempFilePath); unlink($tempFilePath); // ダウンロード後に一時ファイルを削除 }, 200, [ 'Content-Type' => 'text/plain', 'Content-Disposition' => 'attachment; filename="laravel.log"', ] ); } else { // ログファイルが存在しない場合の処理 abort(404); } }

試したこと

保存したlogファイルの中身

[2023-12-07 15:14:02] local.DEBUG: eyJpdiI6Ik1zeFFBRk40ZWxO~省略~YWciOiIifQ== [2023-12-07 15:15:07] local.DEBUG: eyJpdiI6IjZ1VTYrNWRldnpG~省略~GMiLCJ0YWciOiIifQ==

logファイルの中身を手動で下記のように調整すれば、エラーが表示されずdecrypt可能でした。

eyJpdiI6Ik1zeFFBRk40ZWxO~省略~YWciOiIifQ==

※日付やlogレベルの表記を削除
※「eyJpdiI6Ik1zeFFBRk40ZWxO~省略~YWciOiIifQ== 」文末にあった謎の空白を削除
※複数行の書き込みがあった場合、最初の一行以外は全て削除

上記検証結果から暗号化した1文のみであればdecrypt可能そうだったので、
ファイルを取得したあと、logが動的に書き込む「日付やlogレベル」とenecryptした内容を分離させて、
enecryptした内容のみにdecrypt処理を行い、最後に分離した内容を結合すれば、
エラーにならないのかな?っと思ったのですが、
そのアプローチが最適なのか分からず、
お知恵を貸していただきたく、
質問させていただきました。

どうか、お力添えのほどをよろしくお願い申し上げます。

コメントを投稿

0 コメント