Frage Wie trennt man die Identität einer Person von ihren persönlichen Daten?


Ich schreibe eine App, deren Hauptzweck es ist, eine Liste von Benutzern zu führen Einkäufe.

Ich möchte sicherstellen, dass auch ich als Entwickler (oder jemand mit vollem Zugriff auf die Datenbank) konnte nicht herausfinden, wie viel Geld a bestimmte Person hat ausgegeben oder was er gekauft hat.

Ich habe zunächst folgendes Schema entwickelt:

    -------------- + ------------ + -----------
    user_hash | Gegenstand | Preis
    -------------- + ------------ + -----------
    a45cd654fe810 | Stripclub | 400,00
    a45cd654fe810 | Ferrari | 1510800,00
    54da2241211c2 | Bier | 5.00
    54da2241211c2 | iPhone | 399,00
  • Benutzer meldet sich mit Benutzername und Passwort an.
  • Aus dem Passwort berechnen user_hash (evtl. mit Salzen etc.).
  • Verwenden Sie den Hash, um auf Benutzerdaten mit normalen SQL-Abfragen zuzugreifen.

Bei genügend Benutzern sollte es fast unmöglich sein zu sagen, wie viel Geld, das ein bestimmter Benutzer ausgegeben hat, indem er nur seinen Namen kennt.

Ist das eine vernünftige Sache oder bin ich völlig dumm?


5
2017-09-11 14:32


Ursprung


Antworten:


Das Problem ist, dass, wenn jemand bereits vollen Zugriff auf die Datenbank hat, es nur eine Frage der Zeit ist, bis sie die Datensätze mit bestimmten Personen verknüpfen. Irgendwo in Ihrer Datenbank (oder in der Anwendung selbst) müssen Sie die Beziehung zwischen dem Benutzer und den Elementen herstellen. Wenn jemand vollen Zugriff hat, haben sie Zugriff auf diesen Mechanismus.

Es gibt absolut keine Möglichkeit, dies zu verhindern.

Die Realität ist, dass wir durch den vollen Zugang in einer Position des Vertrauens sind. Dies bedeutet, dass die Unternehmensleiter darauf vertrauen müssen, dass Sie, obwohl Sie die Daten sehen können, in keiner Weise darauf reagieren werden. Hier kommen kleine Dinge wie Ethik ins Spiel.

Heute trennen viele Unternehmen die Entwicklungs- und Produktionsmitarbeiter. Der Zweck besteht darin, die Entwicklung vom direkten Kontakt mit lebenden (dh realen) Daten zu trennen. Dies hat eine Reihe von Vorteilen, da Sicherheit und Datensicherheit an der Spitze des Heaps liegen.

Der einzige wirkliche Nachteil ist, dass etwas Entwickler glauben, dass sie ein Problem ohne Produktionszugriff nicht beheben können. Dies ist jedoch einfach nicht wahr.

Produktionsmitarbeiter wären dann die einzigen mit Zugriff auf die Live-Server. Sie werden in der Regel in einem größeren Umfang überprüft (Kriminalgeschichte und andere Hintergrund-Checks), die mit der Art der Daten, die Sie schützen müssen, zu tun haben.

Der Punkt von allem ist, dass dies ein Personalproblem ist; und nicht eine, die wirklich mit technischen Mitteln gelöst werden kann.


AKTUALISIEREN

Andere hier scheinen ein sehr wichtiges und wichtiges Puzzleteil zu vermissen. Nämlich, dass die Daten aus einem bestimmten Grund in das System eingegeben werden. Dieser Grund ist fast universell, so dass es geteilt werden kann. Im Falle einer Spesenabrechnung werden diese Daten eingegeben, damit die Buchhaltung wissen kann, wen sie zurückzahlen muss.

Das bedeutet, dass das System auf einer bestimmten Ebene mit Benutzern und Elementen übereinstimmen muss, ohne dass die Dateneingabe-Person (dh ein Verkäufer) angemeldet ist.

Und da diese Daten miteinander verknüpft werden müssen, ohne dass alle beteiligten Parteien dort einen Sicherheitscode eingeben müssen, um die Daten "freizugeben", kann ein DBA die Abfrageprotokolle absolut überprüfen, um herauszufinden, wer wer ist. Und sehr leicht kann ich hinzufügen, egal wie viele Hash-Marken Sie hineinwerfen wollen. Triple DES wird Sie auch nicht retten.

Am Ende des Tages haben Sie lediglich die Entwicklung mit absolut null Sicherheitsnutzen erschwert. Ich kann das nicht genug betonen: Die einzige Möglichkeit, Daten von einem dba zu verstecken, wäre entweder 1. dass Daten zu nur für die Person zugänglich sein, die sie betreten hat oder 2. dass sie überhaupt nicht existiert.

In Bezug auf Option 1, wenn die einzige Person, die jemals darauf zugreifen kann, die Person ist, die sie eingegeben hat ... nun, es hat keinen Sinn, dass sie in einer Unternehmensdatenbank ist.


0
2017-09-17 17:32



Ich fürchte, wenn Ihre Anwendung eine Person mit ihren Daten verknüpfen kann, kann jeder Entwickler / Administrator dies tun.

Das einzige, was Sie tun können, ist es schwieriger zu machen, den Link zu machen, den Entwickler / Admin zu verlangsamen, aber wenn Sie es schwieriger machen, Benutzer mit Daten zu verknüpfen, werden Sie es auch für Ihren Server schwieriger machen.


Idee basiert auf @no Idee:

Sie können eine klassische Benutzer / Passwort-Anmeldung für Ihre Anwendung (Hash-Passwort oder was auch immer) und einen speziellen "Pass" verwenden, um Ihre Daten zu schützen. Dieser "Pass" wird nicht in Ihrer Datenbank gespeichert.

Wenn sich Ihr Kunde bei Ihrer Anwendung anmeldet, müsste ich Benutzer / Passwort / Pass angeben. Der Benutzer / das Passwort wird mit der Datenbank geprüft, und der Pass würde zum Laden / Schreiben von Daten verwendet werden.

Wenn Sie Daten schreiben müssen, erstellen Sie einen Hash Ihres "username / pass" -Paares und speichern diesen als Schlüssel, der Ihren Client mit Ihren Daten verbindet.

Wenn Sie Daten laden müssen, erstellen Sie einen Hash Ihres "username / pass" -Paares und laden alle Daten, die mit diesem Hash übereinstimmen.

Auf diese Weise ist es unmöglich, eine Verbindung zwischen Ihren Daten und Ihrem Benutzer herzustellen.

In einer anderen Hand (wie ich in einem Kommentar zu @no sagte) Vorsicht vor Kollisionen. Plus, wenn Ihr Benutzer einen schlechten "Durchlauf" schreibt, können Sie es nicht überprüfen.


Update: Für den letzten Teil hatte ich eine andere Idee, Sie können in Ihrer Datenbank einen Hash Ihres "Pass / Passwort" Paares speichern, auf diese Weise können Sie überprüfen, ob Ihr "Pass" in Ordnung ist.


4
2017-09-17 17:26



  1. Erstellen Sie eine Benutzertabelle mit:
    1. user_id: eine Identitätsspalte (automatisch generierte ID)
    2. Nutzername
    3. Passwort: stelle sicher, dass es Hashed ist!
  2. Erstellen Sie eine Produkttabelle wie in Ihrem Beispiel:
    1. user_hash
    2. Artikel
    3. Preis

Der user_hash basiert auf der Benutzer-ID, die sich niemals ändert. Benutzername und Passwort können bei Bedarf geändert werden. Wenn sich der Benutzer anmeldet, vergleichen Sie Benutzername / Passwort, um die Benutzer-ID zu erhalten. Sie können den user_hash für die Dauer der Sitzung an den Client oder eine verschlüsselte / indirekte Version des Hashs zurücksenden (dies könnte eine Sitzungs-ID sein, in der der Server den user_hash in der Sitzung speichert).

Jetzt benötigen Sie eine Möglichkeit, die user_id in user_hash zu hacken und geschützt zu halten.

  1. Wenn Sie es clientseitig tun, wie @no vorgeschlagen, muss der Client user_id haben. Große Sicherheitslücken (besonders wenn es sich um eine Web-App handelt), Hash kann leicht manipuliert werden und der Algorithmus ist für die Öffentlichkeit frei zugänglich.
  2. Sie könnten es als Funktion in der Datenbank haben. Schlechte Idee, da die Datenbank alle Teile enthält, um die Datensätze zu verknüpfen.
  3. Für Websites oder Client / Server-Anwendungen können Sie sie auf Ihrem serverseitigen Code haben. Viel besser, aber dann hat ein Entwickler Zugriff auf den Hash-Algorithmus und die Daten.
  4. Lassen Sie einen anderen Entwickler den Hashalgorithmus schreiben (auf den Sie keinen Zugriff haben), und kleben Sie ihn als TCP / Web-Service auf einen anderen Server (auf den Sie auch keinen Zugriff haben). Ihr serverseitiger Code würde dann die Benutzer-ID übergeben und einen Hash zurück erhalten. Sie würden den Algorithmus nicht haben, aber Sie können alle Benutzer-IDs senden, um alle ihre Hashes zurück zu bekommen. Nicht viele Vorteile zu # 3, obwohl der Dienst Logging haben könnte und so zu versuchen, das Risiko zu minimieren.
  5. Wenn es sich lediglich um eine Client-Datenbank-App handelt, haben Sie nur die Auswahlmöglichkeiten # 1 und 2. Ich würde dringend empfehlen, einen weiteren [Business] Layer hinzuzufügen, der serverseitig vom Datenbankserver getrennt ist.

Bearbeiten: Dies überschneidet sich mit einigen der vorherigen Punkte. Habe 3 Server:

  • Authentifizierungsserver: Mitarbeiter A hat Zugriff. Verwaltet die Benutzertabelle. Hat einen Web-Service (mit verschlüsselter Kommunikation), der eine Kombination aus Benutzer und Passwort verwendet. Hashes password, sucht user_id in der Tabelle, generiert user_hash. Auf diese Weise können Sie nicht einfach alle user_ids senden und die Hashes zurück erhalten. Sie müssen das Passwort haben, das nirgendwo gespeichert ist und nur während der Authentifizierung verfügbar ist.
  • Hauptdatenbankserver: Mitarbeiter B hat Zugriff. Speichert nur user_hash. Keine Benutzer-ID, keine Passwörter. Sie können die Daten mithilfe von user_hash verknüpfen, die tatsächlichen Benutzerinformationen befinden sich jedoch an einem anderen Ort.
  • Website-Server: Mitarbeiter B hat Zugriff. Ruft Anmeldeinformationen ab, wird an den Authentifizierungsserver übergeben, erhält einen Hash zurück und verfügt dann über Anmeldeinformationen. Hält Hash in Sitzung zum Schreiben / Abfragen in die Datenbank.

Mitarbeiter A hat also user_id, Benutzername, Passwort und Algorithmus. Mitarbeiter B hat user_hash und Daten. Wenn Mitarbeiter B die Website nicht ändert, um den rohen Benutzer / Passwort zu speichern, hat er keine Möglichkeit, mit den echten Benutzern zu verlinken.

Mit der SQL-Profilerstellung würde Employee A user_id, username und password hash erhalten (da user_hash später im Code generiert wird). Mitarbeiter B würde user_hash und Daten erhalten.


2
2017-09-17 19:03



Die einzige Möglichkeit, sicherzustellen, dass die Daten nicht mit der Person verbunden werden können, zu der sie gehört, besteht darin, die Identitätsinformationen überhaupt nicht aufzuzeichnen (alles anonym zu machen). Dies würde jedoch wahrscheinlich Ihre App sinnlos machen. Du kannst es schwieriger machen, aber du kannst es nicht unmöglich machen.

Das Speichern von Benutzerdaten und das Identifizieren von Informationen in separaten Datenbanken (und möglicherweise auf separaten Servern) und das Verknüpfen der beiden mit einer ID-Nummer ist wahrscheinlich die nächste Sache, die Sie tun können. Auf diese Weise haben Sie die beiden Datensätze so weit wie möglich isoliert. Sie müssen diese ID-Nummer weiterhin als Verbindung zwischen ihnen behalten. Andernfalls könnten Sie die Daten eines Benutzers nicht abrufen.

Außerdem würde ich ein Hash-Passwort nicht als eindeutigen Bezeichner empfehlen. Wenn ein Benutzer sein Kennwort ändert, müssen Sie alle Ihre Datenbanken durchsuchen und aktualisieren, um die alten Hash-Kennwort-IDs durch die neuen zu ersetzen. Es ist normalerweise viel einfacher, eine eindeutige ID zu verwenden, die nicht auf den Informationen des Benutzers basiert (um sicherzustellen, dass sie statisch bleibt).

Dies ist ein soziales Problem und kein technologisches Problem. Die besten Lösungen werden eine soziale Lösung sein. Nach dem Aushärten Ihrer Systeme zum Schutz vor unberechtigtem Zugriff (Hacker, etc.), werden Sie wahrscheinlich bessere Ergebnisse erzielen, indem Sie mit Ihren Benutzern Vertrauen aufbauen und ein System von Richtlinien und Verfahren bezüglich der Datensicherheit implementieren. Enthalten Sie spezifische Strafen für Mitarbeiter, die Kundeninformationen missbrauchen. Da ein einziger Bruch des Kundenvertrauens ausreicht, um Ihren Ruf zu ruinieren und alle Ihre Nutzer zu vertreiben, ist die Versuchung, diese Daten durch diejenigen mit "Top-Level" -Zugriff zu missbrauchen, geringer als Sie vielleicht denken (seit dem Zusammenbruch des Unternehmens normalerweise überwiegt jeden Gewinn).


1
2017-09-17 17:54



Denken Sie daran, dass, auch wenn Sie die identifizierenden Informationen der Person nirgendwo speichern, nur die Verknüpfung von genügend Informationen mit dem gleichen Schlüssel Ihnen erlauben könnte, die Identität der Person herauszufinden, die mit bestimmten Informationen verbunden ist. Für ein einfaches Beispiel könntest du den Stripclub aufrufen und fragen, welcher Kunde einen Ferrari gefahren hat.

Aus diesem Grund müssen Sie, wenn Sie Krankenakten (zur Verwendung in der Forschung usw.) anonymisieren, Geburtstage für Personen über 89 Jahre entfernen (weil Personen, die so alt sind, selten genug sind, dass ein bestimmtes Geburtsdatum auf eine einzelne Person verweisen könnte). und entfernen Sie alle geographischen Kodierungen, die einen Bereich mit weniger als 20.000 Personen angeben. (Sehen http://privacy.med.miami.edu/glossary/xd_identified_health_info.htm)

AOL fand den harten Weg heraus, als sie Suchdaten freigaben, die Leute nur identifiziert werden können, indem sie wissen, welche Suchen mit einer anonymen Person verbunden sind. (Sehen http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)


1
2017-09-17 20:04



Es sieht so aus, als ob du damit richtig liegst, aber du überlegst es einfach (oder ich verstehe es einfach nicht)

Schreiben Sie eine Funktion, die basierend auf der Eingabe eine neue Zeichenfolge erstellt (dies ist ihr Benutzername oder etwas anderes, das sich nicht über die Zeit ändern kann)

Verwenden Sie die zurückgegebene Zeichenfolge als ein Salz, wenn Sie den Benutzer-Hash erstellen (ich würde wiederum die Benutzer-ID oder den Benutzernamen als Eingabe für den Hash-Builder verwenden, da sie sich nicht wie das Passwort oder die E-Mail-Adresse des Benutzers ändern)

Ordnen Sie alle Benutzeraktionen dem Benutzer-Hash zu.

Niemand mit nur Datenbankzugriff kann bestimmen, was zur Hölle der Benutzer bedeutet. Selbst ein Versuch, es durch das Ausprobieren verschiedener Samen- und Salzkombinationen brutal zu erzwingen, wird nutzlos, weil das Salz als eine Variante des Benutzernamens bestimmt wird.

Ich denke, du hast deine eigene Frage mit deinem ersten Beitrag beantwortet.


0
2017-09-17 20:18



Eigentlich gibt es einen Weg, wie du vielleicht tun kannst, wovon du sprichst ...

Sie könnten den Benutzer seinen Namen und sein Passwort in ein Formular eingeben lassen, das ein rein clientseitiges Skript ausführt, das basierend auf dem Namen und PW einen Hash generiert. Dieser Hash wird als eindeutige ID für den Benutzer verwendet und an den Server gesendet. Auf diese Weise kennt der Server den Benutzer nur mit Hash, nicht mit dem Namen.

Damit dies funktioniert, muss sich der Hash jedoch von dem normalen Passwort-Hash unterscheiden, und der Benutzer muss seinen Namen / sein Passwort noch eine weitere Zeit eingeben, bevor der Server ein "Gedächtnis" darüber hat, was diese Person gekauft hat.

Der Server könnte sich daran erinnern, was die Person für die Dauer ihrer Sitzung gekauft und dann "vergessen" hat, da die Datenbank keine Verknüpfung zwischen den Benutzerkonten und den vertraulichen Informationen enthalten würde.

bearbeiten

Als Reaktion auf diejenigen, die sagen, Hashing auf dem Client ist ein Sicherheitsrisiko: Es ist nicht, wenn Sie es richtig machen. Es sollte angenommen werden, dass ein Hash-Algorithmus bekannt oder bekannt ist. Anders zu sagen, bedeutet "Sicherheit durch Dunkelheit". Beim Hashing werden keine privaten Schlüssel verwendet, und dynamische Hashes könnten verwendet werden, um Manipulationen zu verhindern.

Zum Beispiel nehmen Sie einen Hash-Generator wie folgt:

http://baagoe.com/de/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;
}

Siehe wie n ändert sich, jedes Mal, wenn Sie eine Zeichenfolge haseln, erhalten Sie etwas anderes.

  • Hash den Benutzernamen + Passwort mit einem normalen Hash-Algo. Dies ist derselbe wie der Schlüssel der 'geheimen' Tabelle in der Datenbank, wird aber nichts anderem in der Datenbank entsprechen.
  • Hängen Sie den Hash-Pass an den Benutzernamen an und hashen Sie ihn mit dem obigen Algorithmus.
  • Base-16 kodieren var n und fügen Sie es im ursprünglichen Hash mit einem Trennzeichen an.

Dies wird ein erstellen eindeutiger Hash (wird jedes Mal anders sein), die vom System für jede Spalte in der Datenbank überprüft werden kann. Das System kann so eingerichtet werden, dass es einen bestimmten eindeutigen Hash-Wert nur einmal (z. B. einmal pro Jahr) zulässt, um MITM-Angriffe zu verhindern, und keine der Benutzerinformationen über den Draht weitergeleitet werden. Wenn ich etwas nicht verpasse, ist da nichts unsicher.


0
2017-09-17 17:34