Laravel5.6
mysql Ver 15.1 Distrib 5.5.56-MariaDB (本番環境)
mysql Ver 14.14 Distrib 5.7.22, (開発環境)
でアプリケーションを制作しています。
DBに個人を特定する値が入っています。ぶっちゃけると MACAddressなのですが
毎回、500件程にwhereで絞り込んだ後に、およそ100件程のMACAddressの付き合わせ検索を連続で頻繁に行う必要があります。
具体的には外部からhttpsでPOSTされて来る100件程の生のMACAddressの値と、DBの値を比較する処理をしています。
これまでDBにはMACAddressが生データで入力されており、完全一致で検索をかけていましたが、
これをhash化して管理したいと考えています。
そこで検索性が高く、いざというとき(DBデータ盗まれた等)複号化されにくい暗号化の方法としてどのようなものを使うのがふさわしいでしょうか?
まとめると以下の様な条件になります。
・DB検索に時間がかからなければ良い。
・システムとして値の複号化は必須要件ではない。(つまりopenSSL等で複号化をしないでも良い)
・DBの方では一意性が保証できる値となっていれば良い。
・DBの情報が漏洩した際、復元されにくいものが良い。
・md5,sha1 は計算力を使えば複号されるので不採用。
・Laravelファサードの Hash:check() はかなりの処理時間がかかるので不採用。
また、このような要求にこたえられるような暗号化の記述がされたサイト等あれば、
それのみでもご紹介いただけると幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/24 09:17
回答4件
0
・md5,sha1 は計算力を使えば複号されるので不採用。
という前提であれば、SHA-256でも大差はないと考えられます。MD5やSHAシリーズは、ハッシュ値の計算に高速性が求められる要件(たとえばDVDイメージのハッシュ値を求める等)に適したもので、総当たり耐性は弱いです。te2jiさんの指摘のように、MAC Addressは48ビットしかないですし、ベンダー固有の値もあるので、総当たり攻撃はやりやすい条件です。
ということで、パスワードの保存と同じように、ソルトとストレッチングを施したらどうでしょうか?パスワードの保存とは要件が異なるので、レコード毎に異なるソルトをつけることはできませんが、固定のソルトで、かつできるだけソルトを秘匿すれば、元のマックアドレスが知られるリスクを減じることができます。
PHPで実装する場合、password_hashも使えなくはなかったのですが、PHP 7.0でソルトを外部から指定することが非推奨になりましたので、crypt()関数を使うのがよいでしょう。以下は、Blowfishという総当たり攻撃に強いアルゴリズムを使った実装例です。
$mac_key = crypt($mac_address, '$2y$10$ABCDEFGHIJKLMNOPQRSTUV$');
ここで、$10$ のところはストレッチングの回数のパラメータ(回数そのものではない)ですので、実行時間を見ながら調整してください。大きいほど強度は高くなりますが、実行時間はかかります。
ABCDEFGHIJKLMNOPQRSTUVはソルトですので、ランダムな別の値にしたうえで、できるだけ外部に漏れにくい実装を工夫してください。万一ソルトが漏れても、復号には総当たりをするしかないので、それほど神経質になる必要はないと思います。
crypt()関数はバイナリセーフでないので、マックアドレスは16進数など、NULLバイトが入らないようにしてください。
投稿2018/11/24 11:24
編集2018/11/24 12:40総合スコア11705
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/24 12:23
0
ベストアンサー
SHA-1の強度で許容されないのであればSHA-256が最有力になるのではないでしょうか。
で
・DB検索に時間がかからなければ良い。
については、インデックスが適切に貼られていれば問題無いでしょう。
(もしSHA-256処理によるCPU負荷が問題になるのであれば、HW性能と要件が釣り合っていないのでどちらかを変える必要がある)
(前提をひっくり返すことになりますが)
インターネット経由の通信で取得されるMACアドレスは個人や端末を特定できるものでは無い(最も個人に近い箇所でもプロバイダのルータのMACアドレスになるはず)ので、セッションIDを使ったり、cookieでクライアントを特定できるトークンを発行してそちらで特定する方が良い様に思います。
投稿2018/11/24 09:48
総合スコア18728
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/24 10:06
0
・DBの情報が漏洩した際、復元されにくいものが良い。
MACAddress って組み合わせが決まってるから、総当たりでもそこそこ簡単に解析できちゃうんじゃないかなぁ。。。
stretching は必須な気がする。
投稿2018/11/24 11:10
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/24 12:27
退会済みユーザー
2018/11/24 12:46
2018/11/24 14:49
0
皆さまの回答でhash化や暗号化、セキュリティに対する意識をいっそう強く持てる様になりました。
ひとまずWebサーバー側でアドバイスいただいた様に不可逆暗号化して、DBに値を入れる様に実装しましたがやはり暗号化する際のパフォーマンス低下が気になります。そこで、外部から生のMACAddressをPOSTさせて暗号化させるより、その外部自体で先に暗号化をさせてからPOSTをさせた方が、圧倒的にパフォーマンスが出ることが明らかなので、以下のページなどを参考に今回のアドバイスを生かした暗号化をローカル環境のデバイスの方に施そうと思います。
https://ten-snapon.com/archives/1399
回答ありがとうございました。
投稿2018/11/25 07:22
総合スコア203
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/11/25 08:19 編集
2018/11/25 08:42
2018/11/25 08:53
2018/11/25 08:59
2018/11/25 11:20
2018/11/25 13:46 編集
2018/11/25 14:37
2018/11/25 15:16
2018/11/25 15:27
2018/11/25 16:02
2018/11/25 21:32
2018/11/26 05:47
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。