5

はじめに

私は現在、VisualFox Pro データベースからデータ (薬局の記録) を毎日抽出し、その一部を WordPress サイトにアップロードして、薬局のクライアントが安全に閲覧できるようにするプロジェクトに取り組んでいます。私のソフトウェアの一般的な方法論に関してアドバイスをお願いします。コーディングはできますが、正しい方法で行っているかどうかを知る必要があります。PC ソフトウェア (C#/.NET 4.5) と PHP WordPress プラグインの両方を作成しています。

質問 1: 暗号化

私が使用する予定のサーバー側のデータを暗号化するための現在のプロセスは、この記事に基づいています。要約すると、サーバーに保存されている独自の公開鍵を使用して、各ユーザーのデータを非対称に暗号化することを提唱しています。このデータを復号化するための秘密鍵は、ユーザーのパスワードを使用して対称的に暗号化され、保存されます。この方法では、データベースが盗まれた場合でも、ユーザーのパスワード ハッシュを破る必要があり、その場合でも、すべてのユーザーのデータに対してプロセスを繰り返す必要があります。

著者自身が指摘した唯一の弱点であり、私の質問の要点は、ユーザーがログインしている間、復号化されたキーがセッション ストレージに保存されるという事実です。この記事で提案されている対処方法は、ユーザーがログインしている時間を制限することです。より良い解決策は、そのキーを有効期間の短い安全な Cookie に保存することだと思いました (もちろん、プロセス全体は HTTPS 経由で行われます)。 . そうすれば、攻撃者がユーザーのコンピューターを制御し、Cookie を読み取ることができる場合、おそらくパスワードをキーログしてログインすることができ、データベースを盗む必要はありませんが、攻撃者がサーバーへのアクセスを取得したとしても、復号化することはできません。 HTTPS トラフィック (またはできるかどうかはわかりません。)

復号化されたキーを一時的に保存するには、安全な Cookie またはセッション ストレージを使用する必要がありますか?

質問 2: ストレージ

私がまだ解決したい 2 番目のことは、データを保存する方法です。これは、より効率的な問題です。すべてのユーザーが独自の暗号化キーを持っているため、すべてのユーザーのレコードを個別に保存する必要があります。レコードを表すオブジェクトの配列を持つ暗号化された JSON を含む、すべてのユーザーのデータの「ブロック」を保存する必要があるのか​​ 、それとも実際のデータ構造を持つテーブルにレコードを保存し、各データフィールドを暗号化する必要があるのか​​ わかりません鍵とは別に。

私はデータを 1 つのブロックとして保存することに傾いています。おそらく数千の個別のフィールドよりも、一度に 1 つの大きなデータ ブロックを復号化する方が効率的であるように思えます。また、データを適切な構造で保存したとしても、データはすべて BLOB になるため、MySQL の WHERE や ORDERBY などを使用することはできません。

ユーザーごとに大きなブロックとしてデータを保存する必要がありますか、それともさまざまなフィールドに分けて保存する必要がありますか?

質問 3: 転送

DBF ファイルからデータを抽出し、基本的に「差分」を作成します。これにより、前日のデータから抽出された現在のデータを比較し、変更されたユーザーのブロックのみをアップロードします (レコードのみをアップロードすることはできません)。 、おそらくユーザーのデータをブロックに保存することになるため)。また、削除されたユーザーの「削除」手順も含めます。これは、データベースに数十万のレコードがあり、合計で 200 MB を超えており、サイズが毎日増加しているためです。

私の現在の計画は、このすべてのデータを JSON ファイルに書き込み、gzip してサーバーにアップロードすることです。私の質問は、データのセキュリティを確保しながらそれを行うにはどうすればよいですか? 当然、アップロードは HTTPS 経由で行われ、許可されたアップロードのみを許可する API パスワードを設定していますが、私の主な関心事は、サーバーが侵害された場合にデータを保護する方法です. 攻撃者が処理中にサーバーから JSON ファイルを取得することは望ましくありません。私が持っていた 1 つのアイデアは、サーバーにユーザーの公開鍵のリストを送信してもらい、アップロードの前にソフトウェアで暗号化を実行することでした。それがそのデータを保護する唯一の方法であるように私には思えます。おそらくAPIキーまたは特別なパスワードを使用して、JSONファイル全体を暗号化できますが、攻撃者が復号化されたファイルにそのままアクセスできる場合は意味がありません. はサーバー上で処理されています。それは良い解決策ですか?

クライアント側でデータを個別に暗号化する必要がありますか、それともサーバーに安全に転送してそこで暗号化する方法はありますか?

回答ありがとうございます。以前にこのような問題に対処したことがある人から聞いてみたいです。

注: Programmersに相互投稿されました。コメントを参照してください。

4

1 に答える 1

3

質問1

暗号化

たまたま、Wordpress コメントの個人情報 (電子メール、IP) を暗号化する同様のシステムに取り組んでいます。これにより、サーバーが侵害された場合でも、データベース内の機密データは引き続き暗号化されます。非対称復号化キーをセッションに保存することは私には向いていませんでした.

そのため、SSL 証明書を介した Cookie の方が適しています。少なくとも、攻撃者はユーザーがログインするのを待ってからキーを盗む必要があります。これと並行して、ある種のトリップワイヤー システムを使用することをお勧めします。これにより、システムが侵害されると、ユーザーはシステムにログオンできなくなります (したがって、待機している攻撃者にキーを提供できます)。

あなたが言うように、レコードを暗号化する (私の設計では 1 つのキー、またはあなたの設計では多くのキーを使用) ということは、レコードの検索がデータベース サーバーから離れなければならないプロセスになることを意味します。もっとゆっくり。

速度とセキュリティのトレードオフを行うことで、これを軽減できる場合があります。一部のフィールドはファジー化され、暗号化されずに保存されます。たとえば、患者がどこにいるかを検索する場合は、住所から (緯度、経度) を取得し、それにランダムなシフトを適用して (両方の軸でいずれかの方向に最大 3 マイル)、結果の座標を保存します。平文で。位置に関するおおよそのカウント クエリは、復号化せずに実行できます。

クライアント コンピューターへの攻撃を緩和する

上記は、すべてのレコードがそこに保存されているため、最大のリスクであるサーバーに対する攻撃を軽減する方法を示しています。ただし、ご指摘のとおり、クライアント マシンへの攻撃も懸念事項であり、それらが一般のメンバーである場合、セキュリティ プロセスは存在しないと見なすことができます。

これに基づいて、クライアントが 3 つのランダムな文字を選択する必要があるパスフレーズを使用して、単一のパスワード (全体が提供されます) を強化できます (つまり、全体が提供されるわけではありません)。これは、キーロガーに対して 2 つの方法でエレガントに防御します。まず、盗聴しにくいドロップダウン メニューが使用されます。ユーザーがキーボード ショートカットを使用しても、完全なフレーズは提供されません。ログオンが成功するたびに、ランダムな文字 (1、4、5 など) のインデックスが記録され、長期間にわたって再度要求されることはありません。明らかに、間違った回答が多すぎると、アカウントがロックアウトされ、電話または郵便のリセット コードによる再認証が必要になります。

使用できる他の認証方法: ユーザーが正しいパスワードを入力するたびに追加のパスフレーズをテキストで送信するか、(おそらく法外に高価な) オンライン バンキングのような認証デバイスを使用します。

識別情報をほとんどまたはまったく保存しない

セキュリティのためのもう 1 つのヒントは、保存する個人情報をできるだけ少なくすることです。メールですぐにパスワードをリセットできない場合は、名前、住所、電話番号、メールなど、すべての個人を特定するデータはおそらく不要です。その個人情報は、共通の主キーを使用して相互にリンクすることで、別のサーバー上の接続されていないデータベースに個別に保存できます。(実際、ユーザーがパスワードをリセットしたい場合は、匿名のユーザー レコードに対してフラグを保存するだけで済みます。薬剤師は、次に管理パネルにアクセスしたときに、ファイアウォールで保護されたマシンでリセット プロセスを手動で実行できます)。

質問2

表形式のデータを 1 つの BLOB で暗号化するか、それとも各列に残す必要がありますか? 私は自分のアプリケーションでもこれを見てきました。私の場合は、1 つの BLOB に格納しました。これは、私のユース ケースは検索が集中するためであり、行ごとに 1 つではなく N 個の復号化を行うことで、決定が容易になりました。とは言うものの、列を個別に暗号化することの整頓を好むかもしれません。破損が忍び寄る場合、それらを分離することで、行の一部が生き残る可能性が高くなると主張することができます.

単一のブロブに保存する場合は、次のような形式を使用しています (非対称暗号化の前に改行で区切られた行):

1.2      <-- version of this format, so I can add things in the future
key1=value1
key2=value2
...

列に書き込むプロセスが複数ある場合は、読み取りと書き込みの間で行をロックするようにしてください。そうしないと、(上記のヒントのように) データの一部が失われる可能性があります。

あなたが言うように、その形式の方が適している場合、これは JSON でも同様に可能です。

質問 3

この質問に対する私の理解は次のとおりです。ユーザー レコードを自分で復号化できない場合、暗号化されていないオフライン コピーにどのようにレプリケートしますか? ここで、セキュリティの制約を少し緩和して、サーバーに共通の公開鍵を保存し、共通鍵で暗号化された変更の別の記録を保持できないかどうか疑問に思います。これにより、(リモートの安全なマシンで同期ルーチンを実行することによって) 定期的に空にする必要があるテーブルが作成されます。したがって、暗号化されていないデータベース全体を取得する場合に比べて、攻撃者にとって変更テーブルの価値は小さくなります。

もちろん、対応する秘密鍵は薬剤師のコンピューター上にある必要があり、ここでもインターネットから安全にファイアウォールで保護されています。

この設計のリスクは、攻撃者がサーバーの公開鍵を自分のものに置き換えて、後で効果的に暗号化された情報を収集できるようにすることです! ただし、サーバーにトリップワイヤーをインストールしている限り、これは合理的に防御できます。これがトリガーされた場合、Web アプリケーションの動的部分は新しい変更を書き込みません (実際には機能しません)。システムがスキャンされ、安全であると判断されるまで。

于 2013-02-21T20:53:31.533 に答える