web-dev-qa-db-ja.com

検索可能な暗号化のためのCiphersweetライブラリはどの程度安全ですか。重複したエントリのリークが問題にならないのはなぜですか。

php-encryption library を使用してすべてのレコードが暗号化されたmysqlデータベースを取得しているコードベースを現在管理しています。これは、現在のセットアップではうまく機能します。暗号化されたフィールドの1つに基づいてSELECTを実行できるようにする新しいビジネス要件を取得しました。

暗号化された値に基づいて選択することは不可能であるため、私はあちこち検索しました ciphersweet を見つけました。これは新しい(6か月前の)リポジトリで、現在githubスターは136個しかありません。私は、ライブラリの背後にある会社によって書かれた それについてのブログ投稿 を読みました。

この考え方は、プレーンテキストのキー付きハッシュ(HMACなど)を別の列に格納するという一般的な考え方である、ブラインドインデックスに基づいています。ブラインドインデックスキーは暗号化キーとは異なり、データベースサーバーには不明である必要があります。

私が理解している限り(ただし、ここでは間違っている可能性があります)、検索する必要がある値は、列ごとに静的なインデックスキーを使用してハッシュされます。結果の値は、HMAC列で検索されます。レコードが見つかると、暗号化された値が復号化されます。

彼らは、重複したエントリリークがあることを説明します。つまり、すべてのレコードが取得された場合、どのレコードが同じ値を持つかはわかりますが、whatはわかりません。その値です。

私は概念を理解し、それでいいように聞こえますが、私は暗号の専門家ではないので、安全性を本当に判断することはできません。この重複エントリリークを使用して他の攻撃を行うことは、どういうわけか可能ではないですか? Rainbowテーブルを不可能にするために、暗号化には常にIV/Nonce/Saltを含める必要があることを常に学習しました(=インターネットで読んでください)。列ごとに静的インデックスキーを使用すると、これらのRainbowテーブルは使用できなくなると思います。

基本的に私はここで何かを逃しているような感覚を持っています。重複エントリのリークが突然問題にならないのはなぜですか?このライブラリ/テクノロジーについてコメントできる人は他にいますか?

13
kramer65

重要な免責事項:私は雇用主のためにCipherSweetを書きました。サードパーティのセキュリティ専門家による別の方法で検証されない限り、以下のすべては細かい部分で行う必要があります。この回答が多数の票を獲得したとしても、決して受け入れてはなりません。私は、CipherSweetの設計に関するいくつかの基本的な質問に答えようとしているだけで、安全かどうかではなく、他の人を信頼しています。

CipherSweetのセキュリティモデルは、基本的には時間とメモリのトレードオフであり、従来の暗号解読手法よりもクロスワードパズルに似た攻撃のリスクをもたらします(したがって、単に「クロスワードパズル攻撃」と呼びますが、正式な用語「部分的に既知の平文攻撃」は、学術文献で関連するヒットを見つける可能性が高いです)。

この点で、CipherSweetの全体的な設計は安全です。ただし、アプリケーションでブラインドインデックスを設計する際に注意が必要な場合に限ります。いくつかの考慮事項があります。

  1. 各ブラインドインデックスのビットをいくつ保存しますか?
    • ビット数が少ないと、特定のSELECTクエリでの衝突の可能性が高くなります。つまり、復号化後に除外する誤検知が多くなります。
    • ただし、ビット数が少ないと、ブラインドインデックスの有用性も低下します。
  2. 特定の暗号化された列に対してブラインドインデックスをいくつ作成しますか?
    • 作成するインデックスが多いほど、メタデータが攻撃者に漏洩するリスクが高くなります。

もちろん、この設計のセキュリティは、他のいくつかの前提が当てはまる場合にのみ話し合う価値があります。

  1. 各ブラインドインデックスには個別のキーがあります。
  2. 平文をブラインドインデックスに変換するために使用されるハッシュ関数(またはKDF)は、十分に安全です(たとえば、ランダムなOracleモデル)。
  3. 暗号化自体は安全です(たとえば、すべての既知の実用的な攻撃に対して127ビットを超えるセキュリティレベルのAEAD)。

これらの仮定がどのように答えられるかを理解するには、 CipherSweet内部のドキュメント に目を通してください。しかし、要するに、答えは次のとおりです。

  1. CipherSweetは、フィールドごととインデックスごとに異なるキーを使用します マスターキーから派生
  2. 2018年11月現在、 HMAC-SHA384およびBLAKE2b はそのままになっています。
  3. 2018年11月現在、 AES-CTR + HMAC-SHA2およびXChaCha20-Poly1305 はそのままです。

つまり、そうは言っても、未回答の質問は次のとおりです:情報漏えいの危険なレベルをどのように判断するのですか?

  • 明らかに、明確なブラインドインデックスを作成する$plaintext[0]$plaintext[1]、...は、インデックスからプレーンテキスト全体をリークします。
    • この場合、暗号化を解除する必要はありません。パターンを調べてダミーのエントリをコミットし、それを非常に非効率的な置換暗号として扱います。
  • 逆に、プレーンテキスト全体の単一の literal ブラインドインデックス(16ビットに切り捨てられた)は、攻撃者にとって有用なものをほとんどリークしません。
    • データセットが十分に大きい場合、衝突は非常に一般的です。
    • もちろん、これはブラインドインデックスを作成する目的さえほとんど無効にします。

さらに、CipherSweetを使用すると、複合ブラインドインデックスを作成できます。たとえば、次のようにハッシュ化できます。

  1. 個人の名のイニシャル(該当する場合)
  2. 個人の姓のイニシャル(該当する場合)
  3. 個人の社会保障番号の下4桁
  4. 性別/性別を示す1文字(該当する場合)

これにより、個々の入力のキースペースが制限されている場合でも、特定のブラインドインデックスで使用可能なプレーンテキストのキースペースが大幅に増加します。これは特に ブールフィールドでの暗号化/検索 に役立ちます。


上記のすべてを考慮すると、このWebサイトでCipherSweetを信頼するかどうかについて十分な回答を得ることができるかどうかはわかりません。未回答の質問は正確に答えるのは簡単ではなく、詳細な分析が必要になります。

言われていること:そのセキュリティ目標を損なう方法でCipherSweetを誤用することは確かに可能です。それはツールです。

プロトコル設計に深い欠陥がない限り、CipherSweetを安全に使用することができます[〜#〜] [〜#〜]できるはずです。安全な場合でも、ほぼ確実にセキュリティの専門家が使用方法を再確認します。

12

免責事項:公開されたとき(または少なくとも私がそれに気付いたとき)に暗号スイートの設計と実装を調査している間、本格的な監査とセキュリティの証明を実行しませんでしたPHP実装については詳しく調べませんでした(ほとんどの場合、PHPの作業を行っていないため))。これを監査レポートと間違えてください(支払われたときにのみ作成します:P)。

Ciphersweetは、非常に退屈なデザインを採用しています。スコットはそれを、サイファースウィートのセキュリティ主張とともに彼の答えで説明しているので、これ以上は説明しません。 Ciphersweet、IMOの主なポイントは、他の方法よりも安全で、混乱させるのが難しいことです。

あなたが言及する「重複エントリリーク」は完全なレコード(これらは標準の非決定的暗号化で暗号化されます)には適用されませんが、ブラインドインデックスには適用されます。たとえば、HIVステータスにインデックスを付ける場合、データベースへの読み取りアクセス権を持つユーザーどのレコードが同じHIVステータスになっているのかを把握でき、そこからすべてのレコードのHIVステータスが回復する可能性があります。

これは、基本的な情報の漏えいであり、インデックスをブラインドします:特定の(関数の)HIVステータスを持つすべての行をSELECTするための十分な情報がある場合、 2つの行が同じHIVステータスであるかどうかを確認するのに十分な情報があるので、より洗練された暗号化は役に立ちません(確定的暗号化、順序保持/公開暗号化の使用など)。

他の設計(順序を明らかにする暗号化など)とは異なり、(未知のキーの下にある)キー付きハッシュでは、値が等しいかどうかよりも多くの情報が明らかになりません。

明らかに、(HIVステータスの例で示されているように)十分ではないため、使用できる主な緩和策は3つあります(Ciphersweetがそれらすべてをサポートします)。

  1. 最も明白なのは、非常に機密性の高いデータにブラインドインデックスを追加しないことです。HIVステータスデータを公開したくない場合、効率的にクエリを実行するためにインデックスを作成するのはなぜですか。

  2. 複合インデックスを使用する:インデックスを付ける必要のあるデータがエントロピーが低すぎてブラインドインデックス(HIVステータスなど)に安全に入れられない場合は、他のいくつかのデータと一緒にハッシュすることができます(ドキュメントではSSNを使用しています)例)、および特定のHIVステータスを持つSELECTingレコードをサポートおよび特定のSSN。

    これはIMOです。あまり役に立たないオプションです。SSNによってSELECTを直接(SSNのブラインドインデックスがあると仮定して)でき、解読されたレコードのHIVステータスを確認できるためです。いずれかのフィールドにインデックスを付けることができない場合に備えてください(それらはすべて低エントロピーおよび/または高感度であるため)。

  3. 情報漏えいを減らすために、HMAC値を切り捨てます。たとえば、すべて一意の名前を持つ患者の記録があり、それによる選択をサポートしているとします。特定の患者が存在するかどうかを確認するには、その名前のレコードを(アプリケーションを介して)追加し、アプリケーション自体が検索の許可を与えていない場合でも、データベースに同じ名前のハッシュの2番目のレコードがないか確認します名前による患者。

    切り捨てられたハッシュを使用すると、ブラインドインデックスの各ルックアップで(平均して)少数のレコードが返されるようにすることができます。あなたが平均したい場合は、言う。クエリごとに3レコード、1 000 000レコードのうち、サイズがlog2(10⁶/ 3)〜18ビットのハッシュが必要です。これは私が説明したシナリオを不可能にします。

    Ciphersweetは、データベースのサイズが大きくなるにつれてブラインドインデックスのサイズを拡張するための特別なサポートを提供するとは思いませんが、実行可能であるはずです。ありがたいことに、データベースの拡大に伴ってブラインドインデックスのサイズが変更されないという唯一の問題は、わずかなパフォーマンスオーバーヘッドです。DBが10倍になり、現在10 000 000レコードが含まれている場合、同じ18ビットのブラインドインデックスを保持すると、平均が得られます。 30レコードが選択され、アプリケーションがそれを復号化してフィルタリングします。 30個のレコードを復号化して、興味のあるレコードを見つけると、まだかなり高速です。

[0]実際のユースケースでは、名前の正規化された(小文字、句読点を除いた)バージョンによる選択をおそらくサポートします。 Ciphersweetは関数型インデックスをサポートしています。

TL; DR:Ciphersweetは安全で、ほとんどの代替手段よりもはるかに安全です。すべての暗号化されたデータベースに存在する、注意する必要があるいくつかの警告といくつかの運用上の懸念がありますが、それらはすべて非常に管理可能です。