Laravelにはencrypt
、decrypt
という暗号化、復号のヘルパーメソッドが用意されています。
暗号化 6.x Laravel
https://readouble.com/laravel/6.x/ja/encryption.html
暗号化の結果を見ると、同じ文言でも全く違う文字列になっています。ということは、Laravelの暗号化ではランダム生成された初期化ベクトルを使っているということになりますが、データベースには初期化ベクトルのカラムはありません。初期化ベクトルはどこに保存されているのでしょうか。
前提知識
LaravelはAES-256-CBCという方式で暗号化をしています。この記事を理解するためには、AES、CBC、初期化ベクトルについてある程度の知識が必要です。
プログラマの暗号化入門
https://qiita.com/asksaito/items/1793b8d8b3069b0b8d68
Advanced Encryption Standard
https://ja.wikipedia.org/wiki/Advanced_Encryption_Standard
暗号利用モード
https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%88%A9%E7%94%A8%E3%83%A2%E3%83%BC%E3%83%89
初期化ベクトル
https://ja.wikipedia.org/wiki/%E5%88%9D%E6%9C%9F%E5%8C%96%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB
初期化ベクトル保存場所
encrypt
で暗号化したデータに、初期化ベクトルが含まれています。ただ、base64エンコードされているので、そのままでは読めません。encrypt
で暗号化したデータをbase64デコードすると以下JSONが得られますが、「iv」に初期化ベクトルがセットされています。
{
"iv":"初期化ベクトル",
"value":"暗号化された文言",
"mac":"メッセージ認証符号"
}
動くコードで確認する
説明だけだとしっくりこないと思うので、実際に動くコードで確認しましょう。以下URLに今回使うコード一式をアップロードしました。
コードの動かし方は、リンク先を参照してください。コードの本体はLaravelカスタムコマンドで、ファイルパスはapp/Console/Commands/EncryptIV.php
です。ボイラープレートのせいで行数が無駄に多いですが、handleメソッドがサンプルコードのメインです。プログラムを実行すると、前セクションで紹介した「暗号化のbase64デコード結果」が出力されます。
public function handle()
{
// 勉強用に暗号化前の情報をコンソール出力している
// ただ、セキュリティ上の問題があるので、本番環境では絶対にこのようなコードを書いてはいけない
$origin = "オリジナルメッセージ";
$this->info("origin: {$origin}");
$encrpted = encrypt($origin);
$this->info("encrpted: {$encrpted}");
$base64Decoded = base64_decode($encrpted);
$this->info("base64Decoded: {$base64Decoded}");
}