attr_encrypted を使用して多くのフィールドを格納しています。問題は、私ができるようにする必要があることです 探す これらのフィールドの一部。
取る User.name
。
現在のデータベースにはUser.e_name
およびUser.e_name_iv
。これはかなり安全なようですが、「Joe Bloggs」でデータベースを検索できません。
次に、3番目のハッシュフィールド(User.e_name_hash
)ハッシュ化された検索語に基づいてフィールドを検索するために使用できます。したがって、「Joe Bloggs」検索は、他のすべてのハッシュエントリと比較してハッシュされ、必要なレコードが見つかります。しかし、これを行うには、そのテーブルのそのフィールドのすべてのデータにわたって定数saltが必要です(これも安全ではありません)。
一定のソルトは恐ろしく安全ではないことを知ったので、暗号化されたフィールドを検索可能にするための最良の方法に関するアイデアが不足しています。私のオプションは:
検索に必要なフィールドは超高感度ではないことに注意してください。これらは医療記録や機密情報とは異なります。
あなたのおすすめは何ですか?
あなたはすでに答えを知っています:セキュリティが必要な場合は3。
これが非常に遅くなる場合は、より良いコンピューター、または複数のコンピューターが必要です。それと同じくらい簡単です。
とにかく、どのようなデータの機密性を判断できるとは思わないでくださいこれは人や状況によって大きく異なるため。実話:バニラのアイスクリームを食べたことが知られているため、年間収入の20%を失っている人。これがどのように起こるか想像できませんか?まさにそれが理由です。他人に何を秘密にして何を秘密にしないかを決めないでください。 。
編集済み:最後に重要なメモを参照してください。これは、私が最初に投稿した後に追加され、質問を再度読みました。
私が考えることができる唯一のことは、ハッシュを使用してインデックス付きテーブルを作成することです。ただし、これは、ユーザーのデータの内容に関する情報を漏らすハッシュテーブルの内容に関する情報を漏らさない(うまくいけば)完全な暗号化を交換しているため、セキュリティが低下することは間違いありません(索引付けされた用語の数がわかっているため)特定のアカウントは、とりわけ、周波数分析のための攻撃の足掛かりを与えます)。
注:私は次のことを前提としています。ユーザーごとに異なるivがあるとします。
データベースの行を暗号化する前に、行を読み取り、それらのアイテムにインデックスを付けるテーブルにトークン化できます。次に、ivから生成されたソルトを使用してトークンをハッシュします。したがって、現在、特定のユーザーの場合、「secretfoo」はc9a60f248c3a99e2b7004061d5c74e5f2240426f1f0f95eaf5843aa875e68542
としてインデックスに保存されます。
検索するときは、すべてのIVをループしてすべてのソルトを生成し、トークンc9a60f248c3a99e2b7004061d5c74e5f2240426f1f0f95eaf5843aa875e68542
を検索して「secretfoo」を含むレコードを見つける必要があります。
これはより高速な検索になりますが、ここではセキュリティと速度のトレードオフがあります。与えられたWordのハッシュのディクショナリを基本的に保存しているので、データベースが持ち出された場合、インデックス付けされた情報を使用して元のデータを組み立てることができます(可能性は低いですが)。少なくとも、データに関するメタデータを組み立てるために使用できます。そうは言っても、それは計算的に難しいでしょう。
100,000人のユーザーがいて、ユーザーあたり約100行の合計テーブルサイズが100,000,000行のデータがあるとします。
1億件すべてを復号化してインデックス付けされていない検索を実行するには、膨大な時間がかかります。
上記のパラダイムでは、必要なレコードを見つけるために、100,000のハッシュを生成し、インデックス内の各1回を検索するだけで済みます。さらに、文字列全体(ハッシュ)を照合でき、部分文字列検索を実行する必要はありません。
これには、100,000のハッシュを計算し、BTREEインデックス付きテーブルで100,000の検索を実行できるという利点があります。
Mike Ounsworthが指摘したように、検索を行うためには、機密データと機密データでないデータを決定する必要があります。ただし、SHA256ハッシュされたすべてのトークンを使用することは桁数平文よりも優れています。
[〜#〜]編集済み[〜#〜]:
私の投稿を作成した後、私はあなたの質問を再読し、ivをデータベースに保存したことを認識しました。これにより、インデックスが流出に対して脆弱になります。
これを修正する唯一の方法は、Webに公開されておらず、API経由でのみアクセスできるseparateデータベースにivを保存することです。これは、PCI準拠のアプリケーションで一般的な設定です。
クエリを作成するとき、Web向けアプリケーションは、ハッシュを生成するivをセキュアサーバーに要求し、検索を実行する必要があります。
これはより複雑な実装ですが、ivがWebに面しているデータベースにあり、それが外部に流出している場合は、ivをループしてインデックス全体を復号化するだけです。
CryptDB を見てください。データベース全体を暗号化し、DB側で復号化せずに、暗号化されたデータに対してクエリを実行します。 CryptDBで動作するようにアプリを少し変更する必要がありますが、著者はこれらがマイナーな変更であると主張しています。それは完全に言語に依存しません。
これが whitepaper のしくみです。
ホットデータ(クエリ対象のデータ)を暗号化された形式で保持し、検索時に復号化する必要がある場合は、データベースの速度が低下し、基本的には高度な検索の最適化を実行できなくなります。毎回全表スキャン。もう1つのオプションはTDEです。
お役に立てれば。これらの要件を明確にした場合は、戻って提案を編集できます。
うん、それは行き詰まりのようです。あなたが巧妙な暗号トラックを探しているなら、あなたはそれを見つけることができません。
プロパティの1つは、暗号化と呼ばれるciphertext indistinguishabilityです。これは、暗号テキストとランダムな文字列が与えられた場合、攻撃者はどちらがどれであるかを判別できないことを意味します。当然の結果として、3つの暗号文があり、そのうちの2つが同じ平文からのものである場合、攻撃者はそれを知ることができません。これが、各レコードに固有のソルトまたは固有のIVを使用するポイントです。
暗号文を検索できるという考え方は、暗号文を区別できないという基本的なレベルで衝突します。
ここでの意味は、検索キーを暗号化することはできず、あらゆる種類のパフォーマンスを維持できないことです。機密性の高いものを決定し、それらを検索できないことを受け入れる必要があります。すべてにランダムIDを貼り付け、ルックアップテーブルを増やすことで、これをある程度設計できる場合があります。