Welches Hash Verfahren bei Daten mit wenig Möglichkeiten?

Guten Tag,

wir müssen bestimmte Nutzerdaten speichern, welche wir jedoch nicht im Klartext speichern dürfen. Deshalb wollten wir diese Daten hashen. Allerdings haben wir das Problem, dass es „nur“ 20.000.000 Möglichkeiten dieser Daten gibt. Wenn ich nun also via SHA256 hashe, könnte ich einfach eine Rainbow Table Attacke durchführen. Also für alle 20 Mio. Möglichkeiten den Hash generieren und dann mit der Datenbank abgleichen. 20 Mio. finde ich nicht wirklich viele Möglichkeiten und die entsprechende Rainbow Table sollte ja schnell erstellt sein.

Meine Frage ist nun, ob ihr eine Idee habt, wie wir die Rainbow Table Attacke verhindern könnten? Uns ist es wichtig, dass wir selber als Betreiber auch nicht die Möglichkeit haben auf irgendeinen Weg die gehashten Daten zu entschlüsseln.

Also wenn wir jetzt als Betreiber einen Salt berechnen und diesen dann zusammen mit den Nutzerdaten hashen, dann wissen wir ja als Betreiber wie sich der Salt berechnet. Ergo könnten wir dann ja eine Rainbow Table Attacke gegen uns selber machen. Und ein Angreifer könnte ja auch an die Information kommen, wie sich der Salt berechnet.

Es ist halt auch wichtig, dass wir in der Zukunft die Nutzerdaten abgleichen können. Also ein Nutzer gibt die Daten ein und dann werden diese gehasht. Wenn der Nutzer diese Daten nun 2 Monate später erneut eingibt, dann soll das natürlich mit dem Hash in der Datenbank verknüpft werden, welcher vor 2 Monaten erstellt wurde.

Vielleicht hat hier ja jemand eine Idee, wie man mit sowas umgeht.

Vielen Dank also schon mal im voraus!

Hallo @KlausBan ,

ich denke dafür gibt es keine rein technische Lösung. Da Ihr die Eingabe des Kunden immer mit den Hashes abgleichen wollt, welche Ihr schon habt, müsste Ihr zwangsläufig Kenntnis über die Hashfunktion und gegebenenfalls des Salts sein. Das schließt ja defacto aus dass Ihr keine Kenntnis darüber haben wollt um nicht selbst den Klartext durch Rainbowtable zu extrahieren.

Mein erster Gedanke dazu, ist zum einem die zusätzliche (zum individuellen SALT des Kunden) Verwendung eines Peppers, der Systemweit gilt. Und als zweiten Faktor könnt ihr versuchen die Rainbow Table Attacke unattraktiv zu machen in dem Ihr die Kosten für Berechnung des Hash erhöht.

Das könnt Ihr machen in dem Ihr Eingabe des Kunden (mit Salz und Pfeffer) hasht und diesen hash dann wieder hasht und wieder und wieder… Hier gilt es Abzuwägen wie lange kann man den Kunden zumuten darauf zu warten bis seine Eingabe gehasht wurde.

# PSEUDOCODE
$input = 'STRING'; # Hier noch salz und pffer dazu denken
$hash = hash_string($input, 3500);

function hash_string($string, $iteration) {
$hash = $string;
    for($i = 0; $i < $iteration; $i++) {
        echo $i.' - '.$hash;
        $hash = sha256($hash);
    }
return $hash
}

// Output
0 - STRING
1 - e5089e403ce9873d8e9af3abd5cbde11929d2938c6bdaff6d4255b499877904b
2 - d8187ef486a8ef7ad7789c9bd5f57117616dd5bdeebd535ebfd0b689871c973c
usw...
3489 - d8187ef486a8ef7ad7789c9bd5f57117616dd5bdeebd535ebfd0b689871c973c

Der Kunde muss jetzt vielleicht 3 Sekunden warten bis die Eingaben gehasht sind, aber der Rainbow Table Angriff darauf wird um Faktor 3.500 aufwendiger.

Einige Hashfunktionen (bcrypt) bieten auch schon per default einen Timecost oder Cost Parameter.

Wenn es nicht genug Möglichkeiten gibt, sammelt halt mehrere Eingaben zu einem Paket. Dann gibt es genug Variationen.

Wobei ich überhaupt nicht verstehe, warum da überhaupt Daten gepeichert werden sollen, auf die ihr selber keinen Zugriff habt. Die Kunden werden doch wohl ihr Geburtsdatum selber wissen, warum sollten sie das bei euch ablegen? Insofern: diese Daten einfach beim Kunden lassen, dort sind sie ja wohl sicher. Warum in aller Welt sollten die kunden die gleihen geheimen Daten auch noch mehrfach bei euch speichern und dann später vergleichen, ob es noch die gleichen Daten sind? Das ergibt doch gar keinen Sinn.

Gruß
loderunner

Wenn der Betreiber das Geburtsdatum verifizieren will, ohne es selber kennen zu müssen…
dann macht es Sinn es als hash zu speichern. Gibt der Kunde es ein, kann der Betreiber es verifizieren ohne es zu kennen.

Klassisches Beispiel ist doch META und WhatsApp. WhatsApp gleicht die Telefonnummern des eigenen Adressbuches mit seiner Datenbank ab. Datenschutzrechtliche Bedenken, werden aber abgewiegelt in dem man ja beteuert, die Telefonnummern wird vor dem Abgleich ja gehasht und nur die Hashes werden abgeglichen. In der Theorie ist diese Vorgehensweise löblich, praktisch ist die Anzahl verfügbarer Telefonnummern aber endlich, dementsprechend ist WhatsApp durchaus in der Lage mit einer entsprechenden Rainbow Table aus den gespeicherten Hashes wieder klartext zu machen.

EDIT: Wenn ich so drüber nachdenke, ist die Datenbank von WhatsApp indirekt so eine Art rainbow Table… zar ohne klartext, aber ich würde mal behaupten das 95% aller Telefonnummern auf der Welt in deren Datenbanken zu finden sind.

Hier kann sich bcrypt mit einem frischen Hash eignen.
Eigenschaft von bcrypt: Langsam.
Wenn es aber um Suchbarkeit geht, könnte ich mir vorstellen, dass am sich vielleicht ansehen könnte, den SALT aus SHA3-256 oder so erstellen.

h = bcrypt (< Iterationen >, sha3-256(m), m)

Suche funktioniert, da nur „m“ verwendet wird.
Ein Server-Secret schadet sicher auch nicht und könnte eingefügt werden.

Schutz kommt durch Proof of Work zustande.

Die Angaben zum Einsatz und Zweck sind mir leider nicht 100% klar:

… gehashten Daten zu entschlüsseln

Ist leider ein Fehler in sich: Ein Hash ist eine Einwegfunktion, somit ist eine Umkehrung (Entschlüsselung) nicht möglich.

Bei wenigen Eingaben ist eine Möglichkeit, die Sicherheit zu erhöhen, den Aufwand/Kosten zu erhöhen: Für den regulären Nutzer unschön, für den Angreifer aufwendig.
Alternative: Trennung von Daten und Verteilung auf mehrere Systeme, d.h. ein Angreifer müsste mehrere Systeme kompromittieren. Idealerweise unterschiedliche Systeme (Win & Linux / Software A & Software B auf 2 Systemen).