クレジットカード番号の単純なSHA-1を保存しないでください。解読するのは非常に簡単です(特に最後の4桁がわかっているため)。私の会社でも同じ問題がありました。これが私たちがそれを解決した方法です。
最初の解決策
- クレジットカードごとに、下4桁、有効期限、長いランダムソルト(50バイト長)、およびCC番号のソルトハッシュを格納します。bcryptハッシュアルゴリズムを使用するのは、それが非常に安全であり、必要に応じてCPUを集中的に使用するように調整できるためです。非常に高価になるように調整しました(サーバーのハッシュごとに約1秒!)。しかし、代わりにSHA-256を使用して、必要な回数だけ繰り返すことができると思います。
- 新しいCC番号を入力すると、同じ4桁で終わり、同じ有効期限を持つ既存のCC番号をすべて見つけることから始めます。次に、一致するCCごとに、保存されているソルトハッシュがソルトと新しいCC番号から計算されたソルトハッシュと一致するかどうかを確認します。つまり、かどうかを確認し
hash(stored_CC1_salt+CC2)==stored_CC1_hash
ます。
データベースには約10万枚のクレジットカードがあるため、約10個のハッシュを計算する必要があり、約10秒で結果が得られます。私たちの場合、これは問題ありませんが、bcryptを少し調整することをお勧めします。残念ながら、そうすると、このソリューションの安全性は低下します。一方、bcryptをさらにCPUを集中的に使用するように調整すると、CC番号の照合に時間がかかります。
このソリューションは、CC番号の無塩ハッシュを単に保存するよりもはるかに優れていると思いますが、意欲的な海賊(データベースのコピーを取得することに成功)が平均して1枚のクレジットカードを破るのを防ぐことはできません。 2〜5年。したがって、データベースに10万枚のクレジットカードがあり、海賊がCPUを大量に持っている場合、海賊は毎日数枚のクレジットカード番号を回復できます。
これは、ハッシュを自分で計算するべきではないという信念につながります。それを他の誰かに委任する必要があります。これは2番目のソリューションです(この2番目のソリューションに移行中です)。
2番目の解決策
支払いプロバイダーにクレジットカードのエイリアスを生成させるだけです。
- クレジットカードごとに、保存したいもの(たとえば、下4桁と有効期限)とクレジットカード番号のエイリアスを保存するだけです。
- 新しいクレジットカード番号を入力するときは、支払いプロバイダーに連絡してCC番号を伝えます(または、クライアントを支払いプロバイダーにリダイレクトし、支払いプロバイダーのWebサイトで直接CC番号を入力します)。その見返りに、あなたはクレジットカードのエイリアスを手に入れます!それでおしまい。もちろん、支払いプロバイダーがこのオプションを提供していること、および生成されたエイリアスが実際に安全であることを確認する必要があります(たとえば、クレジットカード番号でSHA-1を単純に計算しないようにしてください!)。クレジットカード番号を回復したい場合、海賊はあなたのシステムとあなたの支払いプロバイダーのシステムを壊さなければなりません。
シンプルで、高速で、安全です(少なくとも、支払いプロバイダーがそうであれば)。私が見る唯一の問題は、それがあなたをあなたの支払いプロバイダーに結びつけるということです。
お役に立てれば。