人の身元を個人データから分離する方法は?
-
02-10-2019 - |
質問
私は、ユーザーの購入リストを維持することを主な目的であるアプリを書いています。
開発者としての私(またはデータベースに完全にアクセスできる人)としての私でさえ、特定の人がどれだけのお金を費やしたか、または彼が買ったものを理解できないようにしたいと思います。
私は最初、次のスキームを思いつきました。
--------------+------------+----------- user_hash | item | price --------------+------------+----------- a45cd654fe810 | Strip club | 400.00 a45cd654fe810 | Ferrari | 1510800.00 54da2241211c2 | Beer | 5.00 54da2241211c2 | iPhone | 399.00
- ユーザーはユーザー名とパスワードでログインします。
- パスワードから計算します
user_hash
(おそらく塩漬けなど)。 - ハッシュを使用して、通常のSQL-Queriesを使用してユーザーデータにアクセスします。
十分なユーザーを考えると、特定のユーザーが自分の名前を知っているだけで費やした金額を伝えることはほとんど不可能です。
これは賢明なことですか、それとも私は完全に愚かですか?
解決
問題は、誰かがすでにデータベースに完全にアクセスできる場合、レコードを特定の人々にリンクするのは時間の問題です。データベース(またはアプリケーション自体)のどこかで、ユーザーとアイテムの関係を作成する必要があります。誰かが完全にアクセスできる場合、彼らはそのメカニズムにアクセスできます。
これを防ぐ方法はまったくありません。
現実には、完全にアクセスできることで、私たちは信頼の立場にあります。これは、会社のマネージャーが、データを見ることができても、それに基づいて行動しないことを信頼しなければならないことを意味します。これは、倫理のような小さなものが作用する場所です。
さて、多くの企業が開発と生産スタッフを分離しています。目的は、Live(つまり:実際の)データと直接接触することから開発を削除することです。これには、セキュリティとデータの信頼性がヒープの一番上にあることに多くの利点があります。
唯一の本当の欠点はそれです いくつかの 開発者は、生産アクセスなしで問題をトラブルシューティングできないと考えています。ただし、これは単に真実ではありません。
生産スタッフは、ライブサーバーにアクセスできる唯一のスタッフだけです。それらは通常、あなたが保護しなければならないデータの種類に合意する、より大きな程度(犯罪歴およびその他のバックグラウンドチェック)に吟味されます。
これのすべてのポイントは、これが人事問題であるということです。そして、技術的な手段で本当に解決できるものではありません。
アップデート
ここの他の人は、パズルの非常に重要で重要な部分を欠いているようです。つまり、データが理由でシステムに入力されていること。その理由はほぼ普遍的であるため、共有できます。経費報告書の場合、そのデータが入力され、会計が誰に返済するかを知ることができます。
つまり、システムは、あるレベルで、データ入力担当者(つまり、営業担当者)がログインすることなく、ユーザーとアイテムを一致させる必要があります。
また、データを「リリース」するためにセキュリティコードを入力するためにそこに立っているすべての関係者が関与しない限り、そのデータを結び付けなければならないので、DBAはクエリログを絶対に確認して誰が誰であるかを把握することができます。そして、あなたがそれに投げたいハッシュマークの数に関係なく、私は非常に簡単に追加するかもしれません。トリプルデスもあなたを救いません。
一日の終わりに、あなたがしたことは、セキュリティの利益が絶対にゼロで開発を難しくすることだけです。私はこれを十分に強調することはできません:DBAからデータを隠す唯一の方法は、どちらかです。 それだけ それを入力したまさにその人がアクセスできるのか、それがそもそも存在しないように。
オプション1に関しては、それにアクセスできる唯一の人がそれに入った人である場合。まあ、それが企業データベースにあることは意味がありません。
他のヒント
あなたのアプリケーションがその人をそのデータにリンクできる場合、開発者/管理者はできることを恐れています。
あなたができる唯一のことは、開発者/管理者を遅くするためにリンクを実行するのを難しくすることですが、ユーザーをデータにリンクすることを難しくすると、サーバーにとっても難しくなります。
@noのアイデアに基づくアイデア:
クラシックユーザー/パスワードをアプリケーションにログインする(パスワードをハッシュするなど)、およびデータを安全に保つために使用される特別な「パス」を使用できます。この「パス」はデータベースに保存されません。
クライアントがアプリケーションにログインするときは、ユーザー/パスワード/パスを提供する必要があります。ユーザー/パスワードはデータベースでチェックされ、パスはデータの読み込み/書き込みに使用されます。
データを記述する必要がある場合、「ユーザー名/パス」カップルのハッシュを作成し、クライアントをデータにリンクするキーとして保存します。
データをロードする必要がある場合、「ユーザー名/パス」カップルのハッシュを作成し、このハッシュに一致するすべてのデータをロードします。
これにより、データとユーザーの間にリンクを作成することは不可能です。
別の手で、(@noへのコメントで言ったように) 衝突に注意してください. 。さらに、ユーザーが悪い「パス」を書いている場合、確認できません。
更新:最後の部分では、別のアイデアがありました。データベースに「パス/パスワード」カップルのハッシュを保存できます。これにより、「パス」が問題ないかどうかを確認できます。
- でユーザーテーブルを作成します:
- user_id:ID列(自動生成ID)
- ユーザー名
- パスワード:ハッシュしていることを確認してください!
- あなたの例のような製品テーブルを作成します:
- user_hash
- アイテム
- 価格
user_hashは、変更されないuser_idに基づいています。ユーザー名とパスワードは必要に応じて無料で変更できます。ユーザーがログインすると、username/passwordを比較してuser_idを取得します。セッションの期間中、ユーザー_hashをクライアントに送り返すことができます。または、ハッシュの暗号化/間接バージョン(セッションIDである可能性があり、サーバーがセッションでuser_hashを保存します)。
これで、user_idをuser_hashにハッシュして保護する方法が必要です。
- @NOが提案したようにクライアント側を行う場合、クライアントはuser_idを持つ必要があります。ビッグセキュリティホール(特にWebアプリの場合)は、ハッシュを簡単に改ざんし、アルゴリズムを一般に自由に利用できます。
- データベースの関数としてそれを持つことができます。データベースにはレコードをリンクするすべてのピースがあるため、悪い考えがあります。
- Webサイトまたはクライアント/サーバーアプリの場合、サーバー側のコードでそれを使用できます。はるかに優れていますが、1人の開発者がハッシュアルゴリズムとデータにアクセスできます。
- 別の開発者にハッシュアルゴリズム(アクセスできない)を書き込み、TCP/Webサービスとして別のサーバー(アクセスもありません)に固執します。サーバー側のコードは、ユーザーIDを渡してハッシュを取り戻します。アルゴリズムはありませんが、すべてのユーザーIDを送信してすべてのハッシュを取り戻すことができます。 #3にはあまり利点はありませんが、このサービスにはロギングがあり、リスクを最小限に抑えようとする可能性があります。
- 単にクライアントDatabaseアプリである場合、選択肢#1と2のみがあります。データベースサーバーとは別のサーバー側の別の[ビジネス]レイヤーを追加することを強くお勧めします。
編集:これにより、以前のポイントの一部が重複しています。 3つのサーバーがあります:
- 認証サーバー: :従業員Aにアクセスできます。ユーザーテーブルを維持します。ユーザー/パスワードの組み合わせを使用するWebサービス(暗号化された通信を使用して)があります。パスワードをハッシュし、テーブルでuser_idを検索し、user_hashを生成します。このようにして、すべてのuser_idsを単純に送信してハッシュを取り戻すことはできません。どこにも保存されておらず、認証プロセス中にのみ利用可能なパスワードを使用する必要があります。
- メインデータベースサーバー: :従業員Bにアクセスできます。 user_hashのみを保存します。ユーザーID、パスワードなし。 user_hashを使用してデータをリンクできますが、実際のユーザー情報はどこかにあります。
- ウェブサイトサーバー: :従業員Bにアクセスできます。ログイン情報を取得し、認証サーバーに渡し、ハッシュを取り戻し、ログイン情報を処分します。データベースへの書き込み/クエリのために、ハッシュをセッションに保ちます。
したがって、従業員Aにはuser_id、ユーザー名、パスワード、アルゴリズムがあります。従業員Bにはuser_hashとデータがあります。従業員BがRAWユーザー/パスワードを保存するためにWebサイトを変更しない限り、実際のユーザーにリンクする方法はありません。
SQLプロファイリングを使用して、従業員Aはuser_id、ユーザー名、パスワードハッシュを取得します(user_hashはコードの後半で生成されるため)。従業員Bはuser_hashとデータを取得します。
データが属する人に接続できないことを確認する唯一の方法は、そもそもID情報を記録しないことです(すべてを匿名にします)。ただし、これを行うと、アプリが無意味になる可能性が高くなります。これをより困難にすることはできますが、それを不可能にすることはできません。
ユーザーデータを別々のデータベースに保存し、情報を識別し(おそらく別々のサーバーで)、2つをID番号とリンクすることは、おそらく最も近いことです。これにより、2つのデータセットを可能な限り分離しました。そのID番号をそれらの間のリンクとして保持する必要があります。それ以外の場合、ユーザーのデータを取得できません。
さらに、ハッシュされたパスワードを一意の識別子として使用することはお勧めしません。ユーザーがパスワードを変更すると、古いハッシュされたパスワードIDを新しいデータベースに置き換えるために、すべてのデータベースを通過して更新する必要があります。通常、ユーザーの情報に基づいていない一意のIDを使用する方がはるかに簡単です(静的にとどまることを確認するため)。
これは、技術的な問題ではなく、社会問題になります。最良の解決策はソーシャルソリューションになります。不正アクセス(ハッカーなど)を防ぐためにシステムを強化した後、ユーザーとの信頼を確立し、データセキュリティに関するポリシーと手順のシステムを実装することに取り組むためのより良い走行距離が得られるでしょう。顧客情報を誤用する従業員に特定の罰則を含めます。顧客の信頼の単一の違反はあなたの評判を台無しにし、すべてのユーザーを追い払うのに十分であるため、「トップレベルの」アクセスを持つ人々によるこのデータを誤用する誘惑は、あなたが思っているよりも少ないです(通常、会社の崩壊は会社の崩壊なのでゲインを上回る)。
実際に人の識別情報をどこにでも保存しなくても、同じ情報をすべて同じキーに関連付けるだけで、特定の情報に関連付けられている人の身元を把握できるだけであることに注意してください。簡単な例として、ストリップクラブを呼び出して、どの顧客がフェラーリを運転したかを尋ねることができます。
このため、医療記録を識別する場合(研究などで使用するために)、89歳以上の人の誕生日を削除する必要があります(年をとる人は、特定の生年月日が一人を指すことができるほどまれであるため) 20,000人未満を含む領域を指定する地理的コーディングを削除します。 (見る http://privacy.med.miami.edu/glossary/xd_deidentified_health_info.htm)
AOLは、匿名の人にどのような検索が関連付けられているかを知るだけで、人々が識別できるという検索データをリリースしたときに難しい方法を見つけました。 (見る http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)
あなたはこれで順調に進んでいるようですが、あなたはそれを考えすぎています(または私はそれを理解していません)
入力に基づいて新しい文字列を構築する関数(これはユーザー名または残業を変更できない他の何かになります)を作成します
ユーザーハッシュを構築するときに、返された文字列を塩として使用します(ユーザーのパスワードや電子メールのように変更されないため、ハッシュビルダーの入力としてユーザーIDまたはユーザー名を使用します)
すべてのユーザーアクションをユーザーハッシュに関連付けます。
データベースアクセスのみを持つ人は、ユーザーのハッシュが何を意味するのかを判断できません。異なる種子を試してそれを強制する試みでさえ、塩がユーザー名の変形として決定されるため、塩の組み合わせは役に立たなくなります。
最初の投稿で自分の質問に答えたと思います。
実際、あなたが話していることをする方法があります...
ユーザーは、名前とPWに基づいてハッシュを生成する純粋にクライアント側のスクリプトを実行するフォームに、ユーザーに彼の名前とパスワードを入力させることができます。そのハッシュは、ユーザーの一意のIDとして使用され、サーバーに送信されます。このようにして、サーバーは名前ではなくハッシュでユーザーのみを知っています。
ただし、これが機能するためには、ハッシュは通常のパスワードハッシュとは異なる必要があり、ユーザーは、サーバーがその人が購入したものの「メモリ」を「メモリ」する前に、名前 /パスワードを入力する必要があります。
データベースには、ユーザーアカウントと機密情報の間にリンクが含まれていないため、サーバーはセッションの期間中に購入したものを思い出すことができます。
編集
クライアントをハッシュすると言う人に応えて、セキュリティリスクはありません。ハッシュアルゴリズムが既知または既知であると想定する必要があります。それ以外の場合は、「あいまいさによるセキュリティ」に相当します。ハッシュはプライベートキーを伴うものではなく、改ざんを防ぐために動的なハッシュを使用できます。
たとえば、次のようなハッシュジェネレーターを取得します。
http://baagoe.com/en/randommusings/javascript/mash.js
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagoe <baagoe@baagoe.com>, 2010
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
mash.version = 'Mash 0.9';
return mash;
}
方法をご覧ください n
変更するたびに、文字列をハッシュするたびに何か違うものが得られます。
- 通常のハッシュアルゴを使用して、ユーザー名+パスワードをハッシュします。これは、データベース内の「秘密」テーブルのキーと同じですが、データベースでは他に何も一致しません。
- ハッシュドパスをユーザー名に追加し、上記のアルゴリズムでハッシュします。
- Base-16エンコード
var n
デリミッター文字で元のハッシュに追加します。
これは、を作成します ユニークなハッシュ (毎回異なります)データベース内の各列に対してシステムによって確認できます。システムをセットアップすることで、特定の一意のハッシュを1回(年に1回)許可することができ、MITM攻撃を防止し、ユーザーの情報がワイヤー全体に渡されません。私が何かを逃していない限り、これについて不安なことは何もありません。