web-dev-qa-db-ja.com

安静時の暗号化および/またはAES_ENCRYPT

機密データを含むMySQLデータベースのセキュリティを向上させようとしています。私はいくつかの用語を理解するのに苦労しています。私が状況を正しく理解したかどうか誰かに知らせてもらえますか?

保存時の暗号化-これをテーブルレベルで有効にできるようです。テーブル内のすべてのデータは、キーを使用して暗号化されています。誰かがバックアップファイルを入手したり、サーバーに物理的にアクセスしたりした場合、データは保護されます。もちろん、これはキーが他の場所に保存されていることを前提としています。

AES_ENCRYPT-データをテーブルに挿入/更新するときに、AES_ENCRYPT('data', 'password')を使用できます。 SELECTを介してデータをクエリするときは、AES_DECRYPTを使用します

  1. 安静時に暗号化を使用していたと仮定すると、PHPコードでクエリを実行するには、何か別のことをする必要がありますか?データ?私のPHPコードはPDOリクエストを介してデータベースにキーを送信する必要がありますか?またはデータベースのクエリに通常のコードを使用でき、復号化は自動的に処理されますか?

  2. または、保存時の暗号化が何をするのか誤解していて、代わりにAES_ENCRYPTを使用する必要があります/同様に

9
Chris

安静時の暗号化

保管中の暗号化は、データベースが使用/アクセスまたは更新されていないときのデータベース内のデータです。移動中の暗号化は、TLSのようなもので、データ(データベースから)がサーバーからサーバー、ブラウザー、サーバー、ブラウザーなどに転送されます。 TLSは、慎重に処理され、最低限以上のことを行う必要があるという態度でアプローチされた場合、ほとんどの状況で完全に優れています実際にそれを現実的に安全にするため。

典型的な例は、ドメインでLetsEncryptからのTLS証明書を取得し、突然すべてのものが安全であると考える人々です。しかし彼らは彼らのセッションや彼らのクッキーを暗号化しないので、彼らの防御に大きな潜在的な穴を残します。

MySQLの組み込み暗号化システムを使用しないでください。

私はこれを十分に強調することはできません。 MySQLに組み込まれている暗号化システムは、実際の安全なデータ保護には適していません。

ここで非常によく似た質問に対する私の答え 詳細については(単純にコピー/貼り付けしたくない)をお読みください。

さて、あなたが主張するので....ここに:


私は常に理解してきました使用しないでくださいMySQLの組み込みの暗号化機能(SQLでの保存データの暗号化のポイントは、サーバーが侵害された場合、データは[それほど]リスクにさらされません。

MySQLの組み込み機能の問題は、データが「at rest」状態との間で受け渡されるときに適用されないため、任意のデータのプレーンテキストが暗号化される前/暗号化されるときに、MySQLログに記録されます(クエリルックアップなどのストレージシステムの他の場所では暗号化されないため、多数のルックアップからcountの結果から列の値を推測できます)。 これについて詳しくはこちらをご覧ください

暗号化に関しては、 defuse/php-encryption のようないくつかの実証済みのライブラリを使用する必要があります。

このトピックに関する私自身の調査で読んだことから、Magnusが提供する defuse/php-encryption へのリンクは、MySQLがデータの侵害を引き起こすのを防ぐための最良の方法の1つです。 MySQLプログラム/サーバーにデータのプレーンテキスト値を表示させないでください。

-2017年5月7日に投稿された回答。


また 同じ質問に対するビルカーウィンの答え いくつかの貴重な追加の洞察を与えます:

マーティンの答えに+1しますが、その価値についていくつかの情報を追加します。

MySQL 5.7は、InnoDBテーブルスペースの保存時に暗号化を実装しました( https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html )。

MySQL 8.0は、InnoDB REDOログおよびUNDOログファイルの保存時の暗号化も実装すると報告されています( https://dev.mysql.com/doc/refman/8.0/en/innodb-tablespace-encryption.html )。

これでも、クエリログとバイナリログは暗号化されません。そのためには、MySQLの将来のバージョンを待つ必要があります。

なぜそんなに時間がかかるのですか? MySQLのセキュリティエンジニアリングの責任者は、先月のPercona Liveカンファレンスでの鳥のようなセッションで、暗号化の権利を実装するために非常に注意を払っていると述べました。これは、暗号化の機能だけでなく、キーのセキュリティとキーのローテーション、およびその他の使用法も実装することを意味します。これを正しく行うことは非常に複雑であり、非推奨になり、すべての暗号化データベースを無効にするようなものを実装することを望んでいません。

-2017年5月7日に投稿された回答。

クロージングポイント:

セキュリティは複雑です。あなたがそれを適切に行い、あなたの保護タマネギの皮に自信を持っているなら、あなたは多くのことをする必要があります(以下の箇条書きを参照)。しかし、最初に行う必要があるのは次のとおりです。

誰から保護するかを定義する

真剣に。平文の名前とアドレスを盗もうとしている人、サーバーを乗っ取りたい人、単にデータをゴミ箱に捨てたいという理由だけで、異なる戦略が必要です。常にすべての人から身を守ることができるというのは神話ですが、概念的にはこれは不可能です*。したがって、最も可能性の高い攻撃者を定義してから、その進歩を軽減するための最善の方法を見つける必要があります。

MySQLに特有の、いくつかの明確な推奨事項:

  • SQLとPHPを同じサーバー上に保持します。MySQLデータにリモートアクセスしないでください。

  • SQLへの外部アクセスを除外します(したがって、localhostのみです)

  • テーブル名と列名を難読化します。誰かがあなたのデータに侵入し、あなたがusername列の下に%$HDTBJ^BTUETHNUYTを持っている場合、彼らはこの文字化けがおそらくユーザー名であることを知っているので、彼らはあなたの暗号化を破ろうとする非常に良いスタートを切ります。

  • [〜#〜]重要[〜#〜]:テーブルアクセスを本当にロックダウンします。多くのMySQLユーザーを設定し、それぞれが必要なことを実行するための最低限の特権のみを持っています。ユーザーにテーブル(only)を読み取り、特定のテーブルのみを読み取るようにします。ユーザーは特定のテーブルに書き込みますが、他のテーブルにはアクセスできません。 MySQLのいずれかのユーザーが危険にさらされた場合、関心の分離です。そこにあるすべてのデータが自動的に失われるわけではありません。

  • PHP暗号化サービスを使用します。暗号化キーを完全に別の場所に保存します。たとえば、バックアップ専用に使用する別のサーバーを用意し、暗号化キーを取得するために連絡するためだけにアクセスできるようにします。 PHP/MySQLサーバーが危険にさらされている場合、キーサーバーを切断してロックダウンする余地があるため、被害を制限できます。キーサーバーにもバックアップがある場合は、それほどひどく危険にさらされているわけではありません(状況依存

  • 特定のプロセスがいつ実行されているか、どのサーバーユーザー(人ではなくプログラム)が何をしているのかを正確に伝えるために、多くの監視と電子メールインフォーマーを設定します。したがって、MySQLテーブルのサイズを測定するために、予期しないプロセスが午前5時に実行を開始する理由がわかります。 WTF?

  • MySQL AES_ENCRYPTのデータがDBに保存されていなくても「スニッフィング」される可能性はたくさんありますが、Webサイトが危険にさらされた場合(さらに悪いことに、PHPコード)安全ではありません)、タイミング攻撃は、クエリルックアップとデータパケットの戻りのタイミングをとることによってデータの内容を解決できます。

  • セキュリティはブラックホールです。ある時点で、あなたは「これをやった、私は十分にやった」と思うでしょう。完全なセキュリティを備えている人は誰もいません。非常に熱心な組織の中には、十分なセキュリティを備えているものもあります。あなたはあなたが距離を行く前にあなたがどれだけ歩いても構わないと思っているかを理解する必要があります。


*なぜ不可能なのですか?データをすべての脅威から保護するには、常に、ハッシュのように読み取り不能、使用不可である必要があります。ハッシュは常にすべての人から保護されています。ただし、ハッシュをハッシュ解除することはできません。

13
Martin