暗号化に関する一般的な質問があります。私はここで暗号化関連の質問の多くを読みましたが、私の懸念に特に対処するものを見つけることができません。
これは架空のシナリオです。
攻撃者が暗号化キーを知らなくてもクレジットカードを追加できるのは現実的ではないように思えるかもしれませんが、1つのシナリオは、詐欺のように見える一般向けアプリケーションにリクエストを行い、クレジットカードを知っているアプリケーションによって自動的にブラックリストに載せることです。暗号化キー(これは現実を大幅に簡略化したものです)。
以下を提供するソリューションが必要です。
1)O(log(n))仕事以下でブラックリストに登録されたクレジットカードを挿入します
2)クレジットカードがブラックリストに載っているかどうかをO(log(n))作業以下で確認します。たとえば、btreeインデックスはO(log(n))検索作業。
3)データが危険にさらされた場合に番号が使用できないように、クレジットカード番号を暗号化またはハッシュ関数で保護します。
4)攻撃者は値を挿入でき、暗号化/ハッシュされた値を見ることができても、カードがリストにあるかどうかを確認できません。
私の質問は 指紋として使用するためにクレジットカード番号をハッシュする に密接に関連していますが、選択された回答は「新しいカードが入ったとき、ハッシュされた+ソルトされた列と比較することによってそれを調べます。その既存の列と一致する場合、同じ一意の番号識別子を返すことができることがわかります。 O(n)ルックアップ時間を必要とするため、この解決策は受け入れられません。つまり、番号がリストにあるかどうかを確認するために、ブラックリストのすべての行をチェックする必要があります。
最初に提案されたソリューション:典型的な怠惰なプログラマの答え
暗号化しないでください。これらはとにかく悪い不正な数字です。
失敗:これらが悪い顧客だと私たちが思ったからといって、数字を公開する必要があるという意味ではありません。また、100%正確にブラックリストに登録することを意味するわけではありません。さらに、顧客が不正で詐欺を犯したとしても、番号を公開する権利はありません。
2番目に提案された解決策:クレジットカードをソルトなしでハッシュする
これにより、迅速な挿入と迅速な検索が可能になります。カード番号をもう一度ハッシュして、ハッシュされた値がリストにあるかどうかを確認してください。
失敗:問題は、ランダムなカード番号をハッシュし、値がリストにあるかどうかを確認するだけで、攻撃者がクレジットカードをブルートフォースで攻撃できることです。これは遅いハッシュアルゴリズムでも問題です。有効なカード番号のスペースが少なく、各ハッシュはブラックリストの数百万の行をチェックする可能性があるためです(これは架空の状況であることに注意してください。実際に数百万のクレジットカード番号を保存しているわけではありません)。 。
3番目に提案されたソリューション:各行に一意のソルトを含むハッシュ
このソリューションは、crypt(3)または類似のもので簡単に提供できます。ハッシュ値にソルトをシームレスに格納します。ここで、攻撃者がブルートフォースの数を試みた場合、ブルートフォースのソルトも必要になります。これは攻撃を実行不可能にします。失敗:ブラックリストルックアップの実行にはO(n)作業が必要です。各行で低速ハッシュ関数を呼び出す必要があり、パフォーマンスが許容できなくなります。
4番目に提案されたソリューション:グローバルソルトをデータベースの外部に保存したハッシュ(HMAC)
攻撃者は、毎秒数百万のオフラインハッシュを実行する代わりに、パブリックフェイスAPIを使用してハッシュ操作を実行する必要があります。彼らがオフライン攻撃を実行できない理由は、データベースの外部に保存されているグローバルソルトがソルトをブルートフォースできないほど長いためです。
失敗:挿入によって既存の何百万もの行がチェックされる可能性があり、クレジットカードの状態スペースが小さいという事実がまだあります。攻撃者は1日に数千のリクエストを実行し、データベースに重複した結果のリクエストをログに記録できます。重複は、ブラックリストに既に含まれていたクレジットカード番号です
5番目に提案されたソリューション:あいまいさによるセキュリティ
失敗:これは本当のセキュリティではありません。それは魅力的ですが、攻撃者がデータベースを危険にさらしたと仮定すると、彼らが会社内部の管理者であり、私たちが実装したソリューションやアルゴリズムにアクセスできる可能性があります。
6番目に提案されたソリューション:別の小さなテーブルを作成します。
数値をブラックリストに登録する場合、ソルトを含む完全な数値のハッシュをソルトなしでテーブル2に保存し、ソルトなしで(重複を削除して)最後の4桁のハッシュを保存します。番号がブラックリストに登録されているかどうかを確認するときは、表2を確認してください。ほとんどの場合、ヒットはなく、確認は迅速です。まれなケースですが、ヒットしてから、表1をゆっくりとチェックします。
失敗:何千ものレコードを保存している場合、このリストに最後の4桁が存在する可能性が非常に高くなります。 4桁は10000の一意の組み合わせであり、10000のカードエントリでは、ヒットが発生してチェックが遅くなる可能性が高くなります。さらに、攻撃者はテーブル2のエントリがテーブル1で少なくとも1つ一致することを知っています。10000リクエストのみでテーブル1をブルートすることができ、テーブル1の検索スペースを大幅に削減しました。可能なクレジットカード番号スペースのサイズ。表2は、このスペースを100,000,000/10,000 = 10,000に効果的に削減します。つまり、1つのハッシュを元に戻す時間は、アプリケーションがテーブル1をチェックするのにかかる時間とほぼ同じです(テーブル1の10,000行は10,000の低速ハッシュを意味し、ブルートフォースも10,000の低速ハッシュを意味します)。
すべてのソリューションは、ハッシュの代わりに暗号化にも適用されます。暗号化の利点は、攻撃者が公開されているアプリケーションに対してオンラインで攻撃を行わなければならないことです。提案されたソリューション4で指摘されているように、これでも問題は解決しません。さらに、ハッシュの代わりに暗号化のリスクは、暗号化キーが侵害された場合、攻撃者がすべてのプレーンテキスト値をすぐに入手できることです。少なくともハッシュを使用すると、リストのカード番号の一部を総当たりにすることができます。
トークン化についても調査しました https://securosis.com/assets/library/reports/Securosis_Understanding_DBEncryption.V_.1_.pdf 同じ問題が、重複したハッシュではなく重複したトークンに存在します。
PCI-DSSコンプライアンスよりも強力なものが欲しいので注意してください。ソルトは必要ないため、ソリューション2は技術的にPCI_DSSに準拠しています https://www.pcisecuritystandards.org/documents/PCI_DSS_v3.pdf (PDFリンク)
長い投稿でごめんなさい。これが可能かどうか誰かが知っていますか?
これはかなり高い注文、OPであり、完全に実行することは不可能だと思います。それにもかかわらず、ここにいくつかのアイデアがあります。
攻撃者は値を挿入でき、暗号化/ハッシュされた値を見ることができても、カードがリストにあるかどうかを確認できません。
これに対する答えは、誤検知を挿入することです。カードをブラックリストに登録する場合は、PANで構成されるハッシュ(またはハッシュ+暗号化-以下を参照)を計算します。そうでない場合は、ハッシュをPAN + nonceとして計算します。どちらの場合も、レコードを挿入します。カードがブラックリストに登録されているかどうかを確認するには、nonceなしでハッシュを再構成し、それ。
このようにして、ハッカーはレコードが挿入されたことを確認できますが、挿入自体は何も伝えません。
クレジットカード番号を暗号化またはハッシュ関数で保護して、データが侵害された場合に番号が使用できないようにします。
PAN +長く、システム全体の暗号化コショウ(秘密の塩)をハッシュします。
コショウは十分なエントロピーを追加して、キーを知らなければブルートフォースを不可能にします。コショウをデータベースの外部に保存します。
一致を確認するには、対象のPAN=でハッシュを実行し、テーブルを検索します。シークレットはすべてシステム全体なので、Nice B-を含むインデックスを活用できるはずです。探しているO(log(n))パフォーマンスを提供するツリーインデックス。
私があなたの質問で見る最大の問題は:Have the credit card numbers secured with either encryption or a hashing function so that if the data is compromised the numbers will not be usable.
@ Bobson がコメントに記載されているため、これは問題ですEven hashing credit card numbers is problematic. Given the restricted nature of valid card numbers, it's likely that there's only one valid number which hashes to a given hash.
最初は、検索スペースが[0-9] {15-16}または1.11 x 10 ^ 16 ...に制限されていたためだと思いました。これはちょっと悪いですが、オフライン攻撃率はカード番号あたり1.29日です。 ..世界の終わりではない悪い。しかし、もう少し調査したところ、問題は実際にはこれよりもはるかに悪いことがわかりました。
カードの最初の番号:3で始まる場合は、American Express、Diner’s Club、またはCarte Blancheです。 4はVisa、5はMasterCard、6はDiscover用に予約されています。次の5桁は、銀行や信用組合などのカード発行者とクレジットカードの種類を示します。したがって、たとえば、すべてのシティAAdvantage Executive MasterCardは546616で始まり、5はMasterCardを表し、46616はCitiを表します。また、アメリカン航空AAdvantage Executiveカードの1つであるという事実も同様です。 16桁の残りの数字(American Expressの場合は15桁)は、カード所有者の口座番号と1つ以上の「チェックディジット」の両方を表します。 ソース
16桁の数字の場合は、左側の最初の数字から始めて、カードの各交互の数字を2倍にします。 (15桁の番号の場合、左から2番目の番号から始めます。)2桁の番号を追加して、1桁の番号に減らします。 (たとえば、数値の1つが8の場合、2倍の16になると、1 + 6を加算して7になります。)次に、それらを2倍にしていない交互の数値と一緒に追加します。合計が10で割り切れる場合、クレジットカード番号はおそらく有効です。 ソース
つまり、これは、1222-2233-4444-4444という数値では、検索スペースが[0-9] {8}よりもわずかに大きいことを意味します。つまり、
この問題は、実際に流通しているカードの数を考慮するとさらに悪化します
Type of Credit Card 2000 2003 2007 2008 2010 2012
Visa 255 283 321 304 240 261
Mastercard 200 267 279 260 171 174
Store 597 521 546 539 318 455
Oil Company 98 86 73 65 35 60
Discover 50 54 57 58 55 59
American Express 33 36 52 54 49 52
Other 192 185 166 160 124 106
Total 1,425 1,432 1,494 1,440 992 1,167
*cards in millions
これは、データベース(ソルトではない)にも、カード番号自体のほかにハッシュ(ペッパーではない)にもプログラムに格納されていないエントロピーの追加のソースがない限り、クレジットカードのハッシュを格納することを意味します。すべてはお勧めできません。
(実際にはすべきです)誰かがデータベースに何かを追加できる場合、ブラックリストのセキュリティよりも大きな問題があると主張することができます-特権の昇格から始めましょう、管理者スーパーユーザーハッキングなど(データベースを使用するよりも、管理インターフェイスを使用してブラックリストにカードを追加/削除する方がはるかに簡単です)。
また、データベースのオフラインダンプが盗まれる場合は、PANを安全に保つことがあなたの義務です。 PCI DSS評議会によれば、「PANの保管には十分です」と定義されています要件3:保存されているカード会員データを保護するPCI DSSの「要件とセキュリティ評価手順」:
3.4次のいずれかの方法を使用して、保存されている場所(ポータブルデジタルメディア、バックアップメディア、ログを含む)でPANを読み取り不能にレンダリングします。
- 強力な暗号化に基づく一方向ハッシュ(ハッシュはPAN全体のものでなければなりません)
- 切り捨て(ハッシュを使用してPANの切り捨てられたセグメントを置き換えることはできません)
- インデックストークンとパッド(パッドは安全に保管する必要があります)
- 関連するキー管理プロセスと手順を備えた強力な暗号化。
注:PANの切り捨てられたバージョンとハッシュされたバージョンの両方にアクセスできる場合、悪意のある個人が元のPANデータを再構築するのは比較的簡単なことです。同じPANのハッシュバージョンとトランケートバージョンがエンティティの環境に存在する場合、元のPANを再構築するためにハッシュバージョンとトランケートバージョンを関連付けることができないように、追加のコントロールを配置する必要があります。
ただし、下部の注記は、PCI DSS評議会が人々にハッシュを付けないことを期待していたことを意味していると私は主張します。ハッシュとそのセキュリティについては、後で詳しく説明します。
ここに記載するすべてのオプションは、PCI DSS標準ごとに、さまざまなレベルのユーザビリティとパラノイアで「十分」に機能することに注意してください。
(およびマスクされたPANは、PANの最初の6文字と最後の4文字です)
マスクされたPANをブラックリストに使用します。私の歴史の中で、2人のユーザーが同じPANと異なる完全なPANを使用していた貴重な小さなカードを見てきました。おそらく、プログラミングの問題ではなく、ヘルプデスクにすることはまれです。
この不測の事態を防ぐには、マスクされたパンを使用して複数の行(通常は1、ほとんど2でない行)を取得し、ソルトハッシュされたPANと比較すると、グローバルソルトが実行されます。ただし、この時点では、暗号化されたPANを使用することもできます(復号化と比較)。99.99%の時間で1つのレコードと比較するためです。
いいえ、検証を行うためにO(n)レコードを確認する必要はありません。テーブルレベルのペッパーとデータベースインデックスを使用して、塩を捨てます。
セキュリティのハッシュは別の話ですが、次の点に注意してください。
この実装 を見て、一般的な考えをつかんでください。
HSMはそのようなスキームを許可していますか?ダイジェストは通常、ハードウェアHSMで十分にサポートされていないため、同じものに通常の3DES/AESを使用できます。
ECBモードまたはCBCモードの固定IVで、3DESまたはAES暗号(このセクションでは単に「DES」と呼びます。混乱しないでください)を使用します。あいまいなことによるセキュリティ強化のために、PANの一部またはより強力なHSM(ECB暗号化PANまたはその派生物を介してのみアクセス可能な別の暗号文)など、IVの何かをエンコードできます。まともなIV候補として頭に浮かぶ)。
前に説明したのと同じテクニックを使用し、私が提供したコードサンプルに示されているように-グローバルペッパーを使用して-ダイジェストの有無にかかわらず、DESの下で-これにより、攻撃者がデータベースを逃走した場合に確実になります。 &あなたのコードベースとあなたのサーバー設定は、彼が最初にDESを破ることなくRainbow攻撃を開始することができず、DESキーがHSMにあるためこれは「不可能」です。
この場合のECBと固定IV CBCは、ペッパー化されたハッシュ化されたマテリアルの根本的なランダム性のため、「十分」であることに注意してください。
本来の機能を維持しながら、これよりも安全なスキームを作成することはできません。
セキュリティと使いやすさは正反対の2つであり、完全な偏執狂モードに陥らず、賢くなります。完全パラノイアモードは、これまでの私の経験から、興味深い方法で裏目に出る可能性があります。
そうです、もしあなたがセキュリティに関して法王よりも崇拝しようとしているなら、あなたはあなた自身のリスクでそれをします、原理主義者ではなく、賢くなります。最も重要なシステムの保護にエネルギーを集中します-そしてブラックリストはほぼ間違いなくそうです。
私はこれを推測していると思います。ブラックリストを作成する頃には、トランザクションやリスクルールなどの「安全なカードルックアップメカニズム」がすでにあり、問題は通常、数か月前に解決されたからです。そして、これはここでは当てはまりません。
PSはオンラインAPIを取得し、10.000のカード番号のブルートフォース "スキャン"(1 $承認)を試して、プロセッサがそれについて何を伝えているかを確認します。これに対するチェックとバランスが整っています、読んでください:
それらについてもう少し学ぶために。
これは問題をやり直す必要がある場合だと思います。
有効なPANの途方もなく小さいスペースを回避することはできません。すべてのセキュリティは、エントロピー(塩)と仕事(反復)から生じます。あなたはそれを無料で求めています。あなたはそれを無料で手に入れることはできません。
スピードを上げるonly方法は、一種の「プレフィルタ」を作成することにより、ほとんどの場合これらの計算を実行する必要がないことを確認することです。可能性のあるすべてのプレフィルターは、確率的であり、複雑さを保証できないという点で同等です。これらのすべてのプレフィルターは、「セット内にある可能性がある」と「セット内にない」のみを返します。彼らはそのデータを漏らします。これを回避することはできません。
ブルームフィルターのようなよりシンプルで高速なプレフィルターでは、O(1)のナイスファストランニングタイムがありますが、制限付きセットを検索することはできません。提案されたソリューション#6のような2テーブルのアプローチは、検索する正確なセットを提供しますが、より複雑です-o(log(n))。
しかし、待ってください-ソリューション#6は、ブルームフィルターにどのように相当しますか?まあ、ブルームフィルターは「0を検索」または「nを検索」を返します。 「セットにない」または「セットにある可能性がある」ことを示します。 2テーブルソリューションから何が得られますか?
2つのテーブルが存在します。1つはマスクされたPAN(最初の6桁と最後の4桁))で、グローバルソルトでハッシュされ、各レコードはフルPANでフルテーブルの行をポイントし、一意のソルトで強くハッシュされます受信したPANのマスクされたフォームをハッシュし、o(log(n))検索とプレフィルターテーブルを比較します。
o(log(n))検索を実行したので、比較できるハッシュは0-nの可能性があり、数値が小さいほどはるかに可能性が高くなります。 0は「間違いなくセットに含まれていない」、1 +は「セットに含まれている可能性がある」ということになります。その後、強力なハッシュをチェックするための難しい計算が(おそらく少ない)まだいくつかあります。
ブルームフィルターでも、o(log(n)) 2テーブルアプローチでも、その他の方法でも、すべての作業はなんとかして行われます。不正行為はできません。それを微調整しますが、ごまかすことはできません。
他の方法はこれと同等です。簡単に事前検索できるようにしてエントロピーを削減することは、問題の空間を削減することを意味します。次に、それをより大きな問題の空間にマッピングしようとします。つまり、確率で作業しています。
これらは、情報理論の観点からの単なる事実です。そのため、解決策ではなく、問題をやり直すことをお勧めします。