13 Stimmen

MySQL verschlüsselte Spalten

Angenommen, jede Zeile einer Tabelle enthält Daten, die zu einem bestimmten Benutzer gehören. Der Benutzer hat ein Passwort für den Zugang zum System.

Wie kann ich eine Datenspalte mit InnoDB verschlüsseln, so dass niemand außer dem Benutzer, dessen Daten es sind, die Daten lesen kann? Ich dachte an etwas wie die Verwendung einer der MySQL-Verschlüsselungsfunktionen (z.B. AES) mit einem Schlüssel, der auf einem Hash basiert, der aus dem Passwort des Benutzers berechnet wird.

Hat jemand einen Tipp, wie ich das machen kann? Bin ich auf dem richtigen Weg?

Eine der folgenden Antworten

Bei der Änderung des Benutzerpassworts muss der Benutzerschlüssel mit dem neuen Passwort neu verschlüsselt werden, was wesentlich einfacher ist als die Neuverschlüsselung der gesamten Benutzerdaten, die beliebig groß sein können. Der Benutzerschlüssel bleibt während der gesamten Lebensdauer der Benutzerdaten im System gleich.

Wie kann das helfen? Angenommen, das Passwort lautet pass1. Und es gibt eine Reihe von Datensätzen, die mit einem daraus generierten Schlüssel verschlüsselt sind. Wenn der Benutzer nun das Passwort auf pass2 zurücksetzt, habe ich keine Möglichkeit, die Daten zu entschlüsseln, die mit pass1 verschlüsselt wurden. Wenn ein Benutzer das Kennwort komplett vergisst, sind alle verschlüsselten Daten verloren.

0 Stimmen

Auch wenn dies nicht auf Ihre spezielle Situation zutrifft, fand ich diesen Artikel hilfreich, um eine gründlichere Einführung in die damit verbundenen Probleme zu erhalten: i.amniels.com/

11voto

Damir Zekić Punkte 15070

Ich weiß nicht, ob es sinnvoll ist, Daten mit dem Passwort-Hash des Benutzers zu verschlüsseln, insbesondere wenn Sie den Hash selbst in der Datenbank speichern. In diesem Fall kann jeder, der Zugriff auf die verschlüsselten Daten hat, auch auf den Passwort-Hash zugreifen und die Daten entschlüsseln.

Ein anderer Ansatz wäre, die Daten mit dem anwendungsspezifischen Schlüssel zu verschlüsseln, der mit einigen benutzerspezifischen Daten gesalzen wird. Allerdings steht man dann vor einem anderen Problem: Wie kann man den Anwendungsschlüssel sicher speichern? Auf diese Frage weiß ich keine einfache Antwort, aber wenn Sie befürchten, dass Ihre Datenbankdaten kompromittiert werden könnten, reicht es wahrscheinlich aus, ihn in Ihrem Quellcode aufzubewahren, nicht aber den Quellcode selbst, z. B. wenn Ihre Datenbank außerhalb des Standorts gespeichert ist (denken Sie an Amazon S3).

Das Salzen des Anwendungsschlüssels mit dem Kennwort des Benutzers hilft, wenn Sie nur den Hash des Kennworts in der Datenbank aufbewahren, kann aber eine weitere Sicherheitslücke mit sich bringen: Sie müssen das Kennwort des Benutzers im Klartext in der Anwendungssitzung aufbewahren.

Die technische Lösung ist recht einfach und Beispielcode ist verfügbar . Sie können es wie folgt ändern, um die Daten mit dem Anwendungspasswort zu verschlüsseln, das mit einem Passwort-Hash gesalzen wird:

INSERT INTO secure_table VALUES (
  1,
  AES_ENCRYPT(
    'plain text data',
    CONCAT(@application_password, @user_password))
);

In jedem Fall müssten Sie Ihr Anwendungskennwort irgendwo speichern, so dass ich nicht glaube, dass es einen einfachen Ansatz gibt, der perfekte Sicherheit bietet.

Ein anderer Ansatz, den ich mir vorstellen kann, ist, den Benutzer nach einer kurzen PIN zu fragen, die Sie als Verschlüsselungsschlüssel verwenden könnten. Die PIN würde nicht in der Datenbank gespeichert werden, sondern müssten Sie den Benutzer jedes Mal, wenn Sie auf seine Daten zugreifen, danach fragen.

Und natürlich muss man auch an die Machbarkeit der Verschlüsselung denken. Ohne Entschlüsselung können Sie die Daten nicht indizieren oder durchsuchen. Für eine begrenzte Anzahl von Daten (z. B. Kreditkartennummer) ist sie wahrscheinlich erforderlich, aber ich würde es damit nicht übertreiben.

2voto

ididak Punkte 5654

Um eine der in der Frage genannten Antworten zu verdeutlichen: Der "Benutzer-/App-Schlüssel" ist ein zufällig generierter privater Schlüssel, der zur Verschlüsselung der Daten verwendet wird. Der private Schlüssel ändert sich nie (es sei denn, er wird kompromittiert). Sie verschlüsseln und speichern den privaten Schlüssel mit einem Passwort. Da der private Schlüssel viel kleiner ist als die Daten, ist es viel billiger, das Passwort zu ändern: Sie entschlüsseln den privaten Schlüssel einfach mit dem alten Passwort und verschlüsseln ihn mit dem neuen Passwort erneut.

1voto

sagunms Punkte 7234

Für Daten, die nicht benutzerspezifisch (global) sind, könnten Sie vielleicht eine Kombination aus symmetrischer und asymmetrischer Verschlüsselung verwenden. Sie könnten eine extra password Feld, das alle Benutzer eingeben müssen, so dass selbst wenn ein Benutzer sein Kennwort ändert, die globalen Daten für andere Benutzer mit anderen Kennwörtern weiterhin verwendbar sind.

Die extra password kann bitweise mit einem anderen xor'ed werden salt-like string innerhalb des Quellcodes. Zusammen können sie den symmetrischen Hauptschlüssel zur Entschlüsselung eines private key die in der Datenbank gespeichert sind (und sich nie ändern werden). Nach private key entschlüsselt, indem die extra password kann der private Schlüssel entschlüsseln und read alle Daten in der Datenbank. Der private Schlüssel kann als Sitzungsvariable gespeichert werden.

Die public key kann, wie der Name schon sagt, als einfacher Textstring in der Datenbank gespeichert werden. Wenn Sie Folgendes benötigen write zu db, verwenden Sie den öffentlichen Schlüssel, um die Daten zu verschlüsseln.

Sie können den Benutzern routinemäßig eine neue extra password und die statischen Daten erneut verschlüsseln private key , gefolgt von einem xor'ing mit salt-like string .

Wenn es sich um benutzerspezifische Daten handelt, die nicht für andere Benutzer bestimmt sind, können Sie das Kennwort des Benutzers ohne das Feld "Extra-Kennwort" zur Verschlüsselung des privaten Schlüssels verwenden. Der Administrator könnte eine weitere Kopie der privaten Schlüssel für bestimmte Benutzer haben, die mit seinem Kennwort entschlüsselt werden kann.

0voto

Jack Leow Punkte 21300

Ich glaube nicht, dass das der beste Ansatz ist, es sei denn, Sie erzwingen, dass die Benutzer ihr Passwort nie ändern können, oder Sie haben eine Möglichkeit, alles jedes Mal neu zu verschlüsseln, wenn ein Benutzer sein Passwort ändert.

0voto

Fernando Miguélez Punkte 11068

Sie könnten einen weiteren Schlüssel zur Ver-/Entschlüsselung benutzerspezifischer Daten speichern, der beim Anlegen eines neuen Benutzers generiert werden könnte. Nennen wir diesen neuen Schlüssel Benutzerschlüssel. Dieser Benutzerschlüssel sollte ebenfalls in der Datenbank verschlüsselt werden, und der direkteste Ansatz wäre, ihn mit dem Kennwort des Benutzers oder anderen Daten zu verschlüsseln, die das Kennwort enthalten (z. B. das Kennwort und die Erstellungs-/Änderungszeit usw.).

Ich würde den entschlüsselten Benutzerschlüssel in der Sitzung des Benutzers aufbewahren, um innerhalb der Sitzung jederzeit auf die Daten des Benutzers zugreifen zu können.

Bei der Änderung des Benutzerpassworts muss der Benutzerschlüssel mit dem neuen Passwort neu verschlüsselt werden, was wesentlich einfacher ist als die Neuverschlüsselung der gesamten Benutzerdaten, die beliebig groß sein können. Der Benutzerschlüssel bleibt während der gesamten Lebensdauer der Benutzerdaten im System gleich.

Diese Methode kann natürlich nur verwendet werden, wenn die Authentifizierung durch Senden des tatsächlichen Benutzerpassworts an den Server bei der Anmeldung erfolgt, da die Datenbank wünschenswerterweise nur den Hash des Passworts enthält.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X