So durchsuchen Sie eine MySQL-Datenbank mit verschlüsselten Feldern

15

Angenommen, ich muss bestimmte Tabellenfelder einer MySQL- Datenbank verschlüsseln . Außerdem muss ich einige der Felder durchsuchen, die ich verschlüsselt habe.

Wie würde man diese Felder überhaupt durchsuchen?

Das schrittweise Entschlüsseln jedes Datensatzes ist keine Option: Angenommen, ich habe mehrere Tausend Datensätze. Es würde zu viel Zeit und Raum in Anspruch nehmen, jeden Datensatz zu entschlüsseln und zu prüfen, ob jeder einzelne Datensatz mit der Suche übereinstimmt.

UPDATE 07.09.2012

Das Hinzufügen weiterer Details zum Datenbankschema ist in Ordnung , da ich im Begriff bin, eine neue Anwendung zu implementieren. Außerdem muss ich die derzeit in der Produktion laufenden Anwendungen erweitern. Aber auch für diese Anwendung wäre das Hinzufügen weiterer Details in Ordnung.

UPDATE 08.09.2012

Verschlüsselung ist der Kern dieser Frage.

Zugriffsbeschränkungen, wie sie in einigen Antworten vorgeschlagen werden, gelten bereits - entsprechen jedoch nicht den formalen Anforderungen für die Verschlüsselung von Daten.

Diese formale Anforderung ist nicht der Payment Card Industry Data Security Standard [PCI].

SteAp
quelle

Antworten:

11

Offensichtlich sind sie nicht dazu gedacht, angesehen zu werden, daher wäre es problematisch, danach zu suchen.

Ein Trick, den ich in der Vergangenheit angewendet habe, besteht darin, die verschlüsselten Daten vor dem Verschlüsseln zu hashen und den Hash in einer indizierten Spalte zu speichern. Dies funktioniert natürlich nur, wenn Sie nach dem gesamten Wert suchen. Teilwerte haben nicht den gleichen Hash.

Sie könnten dies wahrscheinlich erweitern, indem Sie einen "Volltext" -Index für Hashes erstellen, wenn dies erforderlich ist, aber es könnte sehr schnell kompliziert werden.

NACHTRAG

Es wurde vorgeschlagen, meiner Antwort nach einer längeren Diskussion im Chat eine Fußnote über die Anfälligkeit für Wörterbuchangriffe hinzuzufügen. Daher werde ich dieses potenzielle Sicherheitsrisiko für den obigen Ansatz erörtern.

Wörterbuchangriff: Bei einem Wörterbuchangriff wird eine Liste bekannter Werte vorab gehasht und die Hashes mit Ihrer gehashten Spalte in der Datenbank verglichen. Wenn sie eine Übereinstimmung finden, ist es wahrscheinlich, dass der bekannte Wert tatsächlich das ist, was gehasht wird (dies ist jedoch nicht definitiv, da Hashes nicht garantiert eindeutig sind). Dies wird in der Regel durch Hashing des Werts mit einem zufälligen angehängten oder vorangestellten "salt" abgeschwächt, sodass der Hash nicht mit dem Wörterbuch übereinstimmt. Die obige Antwort kann jedoch kein salt verwenden, da Sie die Suchbarkeit verlieren.

Dieser Angriff ist gefährlich, wenn Sie sich mit Kennwörtern befassen: Wenn Sie ein Wörterbuch mit gängigen Kennwort-Hashes erstellen, können Sie die Tabelle schnell nach diesem Hash-Wert durchsuchen, einen Benutzer mit einem solchen Kennwort identifizieren und die Anmeldeinformationen effektiv extrahieren, um die Identität dieses Benutzers zu stehlen .

Es ist weniger gefährlich für Artikel mit einem hohen Grad an Kardinalität, wie zum Beispiel SSNs, Kreditkartennummern, GUIDs usw. (aber es gibt verschiedene Risiken, die mit der Aufbewahrung verbunden sind. Daher bin ich nicht geneigt, sie zu empfehlen ).

Der Grund dafür ist, dass Sie ein Wörterbuch mit möglichen Werten und deren Hashes vorab erstellt haben müssen, damit ein Wörterbuchangriff funktioniert. Theoretisch könnten Sie ein Wörterbuch aller möglichen SSNs erstellen (eine Milliarde Zeilen, vorausgesetzt, alle Formatierungspermutationen werden entfernt; mehrere Dutzend Billionen Einträge für Kreditkarten) Im Grunde wird es vergleichbar mit einem Brute-Force-Angriff, bei dem Sie jeden Wert systematisch untersuchen.

Sie können auch nach einer bestimmten SSN oder Kreditkartennummer suchen , wenn Sie versuchen, eine SSN einer Person zuzuordnen. Auch dies ist normalerweise nicht der Grund für einen Wörterbuchangriff, aber möglich. Wenn dies ein Risiko ist, das Sie vermeiden müssen, ist meine Antwort keine gute Lösung für Sie.

Da haben Sie es also. Wie bei allen verschlüsselten Daten erfolgt die Verschlüsselung in der Regel aus einem bestimmten Grund. Achten Sie daher auf Ihre Daten und darauf, wovor Sie sie schützen möchten.

Jeremy Holovacs
quelle
Die Diskussion zu dieser Antwort wurde in den Chat verschoben .
Paul White Monica wieder einsetzen
5

Vielleicht möchten Sie einen Blick auf CryptDB werfen . Es ist ein Front-End für MySQL und PostgreSQL, mit dem verschlüsselte Daten transparent gespeichert und abgefragt werden können. Es verschlüsselt und entschlüsselt Daten zwischen der Anwendung und der Datenbank und schreibt Abfragen neu, um die verschlüsselten Daten zu verarbeiten. und durch dynamisches Anpassen des Verschlüsselungsmodus jeder Spalte, um nur so viele Informationen bereitzustellen, wie für die von der Anwendung verwendeten Abfragen erforderlich sind.

Die verschiedenen von CryptDB verwendeten Verschlüsselungsmethoden umfassen:

  • RND , ein vollständig sicheres IND-CPA-Verschlüsselungsschema, bei dem keine Informationen über die Daten (außer deren Vorhandensein und bei Typen mit variabler Länge die Länge) preisgegeben werden, sondern nur das Speichern und Abrufen ohne Abfragen ermöglicht.

  • DET , eine Variante von RND, die deterministisch ist, so dass zwei identische Werte (in derselben Spalte) mit demselben Chiffretext verschlüsselt werden. Unterstützt Gleichheitsabfragen des Formulars WHERE column = 'constant'.

  • OPE , ein auftragserhaltendes Verschlüsselungsschema, das Ungleichheitsabfragen wie z WHERE column > 'constant'.

  • HOM , ein partiell homomorphes Verschlüsselungsschema (Paillier), mit dem verschlüsselte Werte durch Multiplikation der Chiffretexte addiert werden können. Unterstützt SUM()Abfragen, Hinzufügen und Inkrementieren.

  • SEARCH , ein Schema, das die Suche nach Schlüsselwörtern im Formular unterstützt WHERE column LIKE '% word %'.

  • JOIN und OPE-JOIN , Varianten von DET und OPE, mit denen Werte in verschiedenen Spalten miteinander verglichen werden können. Unterstützung für Gleichheits- und Bereichsverknüpfungen.

Die eigentliche Stärke von CryptDB besteht darin, dass die Verschlüsselungsmethode jeder Spalte dynamisch an die angezeigten Abfragen angepasst wird, sodass die langsameren und / oder weniger sicheren Schemata nur für Spalten verwendet werden, für die sie erforderlich sind. Es gibt auch verschiedene andere nützliche Funktionen, z. B. das Verketten von Verschlüsselungsschlüsseln mit Benutzerkennwörtern.

Wenn Sie interessiert sind, sollten Sie sich die auf der CryptDB-Website verlinkten Artikel ansehen, insbesondere "CryptDB: Schutz der Vertraulichkeit durch verschlüsselte Abfrageverarbeitung" von Popa, Redfield, Zeldovich und Balakrishnan ( SOSP 2011 ). In diesen Abhandlungen werden auch die verschiedenen Sicherheits- und Leistungskompromisse bei der Unterstützung verschiedener Abfragetypen ausführlicher beschrieben.

Ilmari Karonen
quelle
1
It works by encrypting and decrypting data as it passes between the application and the database : Dies kann sicherlich zu Problemen führen, wenn die zu durchsuchenden Daten fehlerhaft sind bereits in der Datenbank befinden (verschlüsselt), aber die Abfrage selbst, die die Datenbank offensichtlich erst dann an die CryptDB übergeben (und dann verschlüsselt?). Ich kann nicht verstehen, wie diese Methode überhaupt effizient sein kann?
Martin
3

Ich verstehe nicht, warum die aktuellen Antworten die Anforderungen nicht vollständig in Frage gestellt haben. Deshalb werde ich fragen und es als Antwort belassen.

Was sind die geschäftlichen Gründe? Welche Daten müssen Sie verschlüsseln und warum? Wenn Sie PCI-Konformität suchen, könnte ich einen Aufsatz schreiben.

Fragen zu Ihrer Anforderung:

  • Müssen Sie ein vorhandenes / nicht vorhandenes Ergebnis oder die tatsächlichen Daten zurückgeben?
  • Benötigen Sie eine LIKE-Funktion '% OMG_SEKRIT%'?
  • Wer kann die Daten nicht sehen und warum?

Die RDBMS-Sicherheit wird normalerweise auf Berechtigungsbasis durchgeführt, die vom Benutzer / der Rolle erzwungen wird. Die Daten werden normalerweise vom RDBMS auf der Festplatte verschlüsselt, jedoch nicht in den spaltenweisen Daten selbst, da dies für eine Anwendung, die zum effizienten Speichern und Abrufen von Daten entwickelt wurde, keinen Sinn ergibt.

Nach Benutzer / Rolle / API einschränken. Auf Festplatte verschlüsseln. Wenn Sie wichtigere Daten speichern, würde ich gerne wissen, warum Sie MySQL verwenden.

Philᵀᴹ
quelle
In erster Linie muss ich finden existiert / existiert nicht und dann den spezifischen Datensatz finden. Volle LIKE-Unterstützung wäre in Ordnung. Aber ich frage mich, dass mehr als nur ein Wortvergleich möglich sein wird. Berechtigte Benutzer dürfen Daten einsehen. Die App entschlüsselt diese Elemente, ein legitimer Benutzer hat das Recht, sie anzuzeigen. Berechtigungsbasisschemata sind keine Option.
8.
Was sind die Kriterien für "wichtigere Daten"?
Arcanine
2

Ich untersuche dies und bin auf Ihre Frage gestoßen. Ich neige zu dem in Abschnitt 5.4 des Artikels "Praktische Techniken für die Suche nach verschlüsselten Daten" beschriebenen Ansatz. Http://www.cs.berkeley.edu/~dawnsong/papers/se.pdf

Die grundlegende Aufgabe besteht darin, einen Index zu erstellen, der verschlüsselte Schlüsselwörter enthält, die im verschlüsselten Suchdokument vorhanden sind. Der Trick besteht darin, auch die Stellen im Dokument (oder in der Datenbank) zu verschlüsseln, an denen diese Schlüsselwörter vorhanden sind.

M. Scott Ford
quelle
1

Programmatisch ist eine effiziente Lösung zu

  1. Rufen Sie ALLE Datensätze NUR für das Feld ab, nach dem Sie suchen, mit der Datensatz-ID
  2. entschlüsseln Sie diese in eine temporäre Tabelle
  3. Führen Sie die Suche für diese Tabelle durch
  4. Verwenden Sie die IDs, um die vollständigen Datensätze (alle Felder) abzurufen, die den Suchkriterien entsprechen
  5. entschlüsseln Sie diese und geben Sie sie an den Benutzer zurück

Der Punkt ist, dass 1 und 4 wesentlich kleinere Datensätze sind als das Abrufen und Entschlüsseln aller Felder aller Datensätze am Anfang.

Ich hoffe, das hilft.

Paul B. Hartzog
quelle
Temporäre Tabellen im Klartext sind relativ (dh sehr) einfach zu greifen und zu lesen, stören den Server im richtigen Moment oder kopieren einfach den temp/Ordner und schlagen, Klartext-Werte für die gesamte Spalte sind da, dies ist keine sichere Art der Bedienung
Martin
1

Dies ist mit der vollständigen Suchfunktion unter Verwendung der internen Verschlüsselungsfunktionen von MYSQL möglich.

Hier ist ein Beispiel:

!!! ICH BENUTZE MYSQL ENCODE () HIER DER EINFACHHEIT halber, MYSQL_ENCODE WIRD JETZT ALS INSECURE ANGESEHEN. NUTZEN SIE STATT ANDERER INTERNER MYSQL-FUNKTIONEN !!!

UPDATE my_table
SET field=ENCODE('my_data', 'my_password')
WHERE ID=1;

SELECT DECODE(field, 'my_password') as field FROM my_table
WHERE field LIKE 'data';

Verwenden Sie NICHT ENCODE (), wie aus dem obigen Kommentar hervorgeht, sondern eine der anderen Verschlüsselungsfunktionen ich aufgrund ihrer Einfachheit nur in diesem Beispiel verwende

Wenn Sie dies in einer Anwendung wie PHP tun, können Sie dies in Ihrem DB-Gateway oder in Ihren Repository-Klassen tun, indem Sie eine Liste / ein Array der verschlüsselten Spalten jeder Tabelle in der entsprechenden Gateway-Klasse speichern.

class UserGateway
{
    protected $encrypted_fields = array(
        'username',
        'email'
    );

    public function get($fields, ...)
    {
        foreach ($fields as $k => $field) {
            if (in_array($field, $fields)) {
                $fields[$k] = $this->decodeSelect($field);
            }
        }

        $sql = 'SELECT '.implode(',', $fields);

        //......
    }

    protected function decodeSelect($field)
    {
        return "DECODE($field, $pass) AS $field";
    }
}

Dies ist natürlich ein sehr rauer und unsicherer Code, der nicht ohne wesentliche Verbesserung in der Produktion verwendet werden sollte. Aber es sollte seinen Zweck erfüllen, indem es die allgemeine Idee vermittelt.

Leigh Bicknell
quelle
-1

Angenommen, Sie suchen in SQL und gegen den vollständigen und nicht partiellen Wert (z. B. 'value%') ..., verschlüsseln Sie diese Daten bei der Erfassung der Suchdaten mit demselben Algorithmus, der bei der Verschlüsselung der Daten verwendet wurde, und suchen Sie danach.

Beispielsweise:

Was wäre gewesen:

SELECT FieldA, FieldB 
FROM Table1 
WHERE FieldC = 'Value'

Könnte stattdessen so aussehen:

SELECT FieldA, FieldB 
FROM Table1 
WHERE FieldC = 'hsk&%67ghhks83'
WellyBoot
quelle
1
Nein . Decent Verschlüsselung mit einem Salz - Wert arbeiten , so wenn Sie zum Beispiel für jede Zeile ein einzigartiges Salz hat, dann wird jede Reihe Salz benötigt auf dem Such - String verwendet werden soll, das wird komplex bekommen, und teuer, ziemlich schnell
Martin