fb18.de
/ Off-Topic
/ Hard- und Softwarefragen
Kryptographie in Webanwendungen: Verschlüsseln der Datenbank
Ich entwickle zur Zeit einen Onlineshop, der auf Servern eines handelsüblichen Webhosters laufen wird. Gerne würde ich es irgendwie fertig bringen, die Kundendaten in der Datenbank zu verschlüsseln.
Ich weiß nur nicht, wie ich es anstellen soll, den Schlüssel zu speichern. Ich kann ihn ja schlecht im Klartext in einer Konfigurationsdatei ablegen. Dann kann ich mir den Aufwand ja eigentlich gleich sparen.
Mein erster Gedanke war, für jeden Benutzer den Schlüssel mit seinem Passwort zu verschlüsseln, so dass er zur Verfügung steht, wenn sich der Benutzer eingeloggt hat. Dann besteht aber das Problem, wie ich an den Schlüssel komme, wenn sich einer neuer Benutzer registriert, oder wenn über die "Passwort vergessen"-Funktion ein neues Passwort generiert wird.
Für mich klingt das ganze nach einem unlösbaren Problem. Oder hat jemand eine Idee? Vielleicht gibt es auch ganz andere Wege die man gehen kann, die Kundendaten zu schützen, um nicht offen zu sein wie die Telekom.
Letztlich ist aber natürlich so, dass man zum Beispiel den Admins beim Hoster ohnehin ausgeliefert ist. Allerdings wäre eine Lösung, bei der man wenigstens etwas kriminelle Energie aufbringen muss, um an die Kundendaten zu kommen, immer noch besser, als diese ungeschützt im Klartext in der Datenbank abzulegen.
Schreib deine Software so, dass sie sich schlecht lesen lässt. Zum Beispiel unverständlichen Code in C schreiben und das ganze dann nur compiliert auf den Server laden. Ist für dich natürlich ein Mehraufwand, aber ein potentieller Angreifer wird sich die Mühe vermutlich nicht machen und ein leichteres Opfer suchen ;-)
http://geekz.co.uk/schneierfacts/fact/130Though a superhero, Bruce Schneier disdanes the use of a mask or secret identity as 'security through obscurity'.
;-)
Vielen Dank, Wolf. Das wäre natürlich eine Möglichkeit, allerdings auch eine Kostenfrage, denn bisher ist alles in PHP geschrieben. Die Möglichkeit auch Binärdcode laufen zu lassen, ist meist nur in teureren Hostingpaketen möglich. Müsste ich mal abwägen mit meinem Auftraggeber.
Hat jemand noch andere Ideen?
@ HannesStruss: Du hast natürlich auch eigentlich recht, aber:
Allerdings wäre eine Lösung, bei der man wenigstens etwas kriminelle Energie aufbringen muss, um an die Kundendaten zu kommen, immer noch besser, als diese ungeschützt im Klartext in der Datenbank abzulegen.
PS: Jetzt bitte keine Diskussion darüber, dass PHP sowieso Schrott ist. Ich bin mir über die Vor- und Nachteile im Klaren.
Naja, du musst dich fragen, ob das ganze, was du machen willst wirklich Sinnvoll ist. Sobald ich als Angreifer auf den Server zugreifen kann, kann ich ihm auch einfach falsche PHP-Seiten unterschieben, die mir die Datenbank auslesen und übersichtlich als HTML Tabellen darstellen kann … völlig ohne mir über das Passwort Gedanken machen zu müssen. Meines Erachtens betreibst du hier lediglich Kosmetik. Das Ziel muss hier eher sein, den Server/die Anwendung sicher zu gestalten.
Das einzige was halbwegs gehen könnte, ist die Datenbank auf nen extra Server auszulagern, und das DB-Passwort lediglich im Speicher zu halten. Dann muss halt nach jedem Neustart ein Admin sich eine speziellen Seite Aufrufen, um das Passwort einzugeben …
Meines Erachtens betreibst du hier lediglich Kosmetik.
Genau das ist mir ja sowieso klar. Es geht mir ja auch nicht darum, dass es überhaupt nicht möglich ist, an die Daten zu kommen, sondern dass man dafür kriminelle Energie aufwenden muss.
Wenn man die Daten einfach nur aus der Datenbank kopieren muss, ist dies doch etwas anderes, als wenn man dafür PHP-Seiten manipulieren muss.
Aus Sicht des Kunden des Shops ist es doch so, dass er sobald er seine Daten angibt, sowie weiß, dass da theoretisch Schindluder mit getrieben werden kann. Gegen kriminelle Machenschaften ist er sowieso wehrlos, die könnten ja zum Beispiel auch von mir bzw. dem Shopbetreiber ausgehen.
Das einzige, was er erwarten kann, ist, dass es externen Angreifern möglichst schwer gemacht wird. Dies versuche ich zu erreichen, in dem ich möglichst vorsichtig programmiere. Außerdem erwarte ich natürlich auch vom Hoster, dass er alle erdenklich Maßnahmen ergreift.
Außerdem kann der Kunde erwarten, dass man internen Angreifern seine Daten nicht auf dem Silbertablett serviert. Dass es für diese Gruppe aber unendlich Möglichkeiten gibt alle Schutzmaßnahmen zu umgehen, wenn man es daraufanlegt, lässt sich nicht vermeiden.
Natürlich wäre ein eigener Server im eigenen Rechenzentrum am besten, hält aber der Abwägung von Kosten und Risiko nicht stand.
Das einzige was halbwegs gehen könnte, ist die Datenbank auf nen extra Server auszulagern, und das DB-Passwort lediglich im Speicher zu halten. Dann muss halt nach jedem Neustart ein Admin sich eine speziellen Seite Aufrufen, um das Passwort einzugeben …
Das wäre für die Praxis leider völlig untauglich.
Man könnte ja nicht mit dem Passwort sondern mit dem Benutzernamen + Irgendetwas (Anmeldezeitpunkt o.ä.) verschlüsseln. Das ändert sich auch nicht wenn der Benutzer sein Passwort vergisst. Natürlich kann ein Angreifer der die PHP-Datein hat das "entschlüsseln". Aber eben nur mit dieser "kriminellen Energie". Die Daten wären dann ja verschlüsselt in der DB und somit vor direktem Angucken sicher.
Verschlüsselung kostet aber Rechenleistung. Die ist bei billig Hostern begrenzt. Da sollte man den Betreiber des Shops vielleicht fragen wie viel es ihm wert ist sein Geld zu verdienen. Der kleinste Rootserver z.B. Hetzner kostet mitlerweile leider auch schon 50€ + jemanden der sich gelegentlich darum kümmert, dafür gibt es aber keine "bösen" anderen User und vor dem Admin muss man auch keine Angst mehr haben.
php..
hättest du das gleich in Perl geschrieben, wäre die ganze Mühe nicht nötig ;-)
ich meine, php könnte man auch in bytecode vorübersetzen. das macht's auf jeden fall schwieriger.
[offtopic]TripleROT13![/offtopic]
hättest du das gleich in Perl geschrieben, wäre die ganze Mühe nicht nötig ;-)
Wieso?
Wie wäre es mit:
1. Benutzer meldet sich mit Usernamen und Passwort an
2. Username wird durch ne Hashfunktion gejagt, das Ergebnis ist der PK der eines Tupels (hashed_username, crypted_userdatensatz)
3. Der verschlüsselte Userdatensatz wird mit den ungehashten Usernamen entschlüsselt.
4. Das eingegebene Password wird gehasht und mit dem eben entschlüsselten Passworthash verglichen
5. Tada
NB:
_ Kommt die DB in falsche Hände, kann man nur durch Raten der jeweiligen Usernamen einzelne Datensätze entschlüsseln, da die Hashfunktion nicht umkehrbar ist.
_ Benutzer kann sein Passwort vergessen, an den Usernamen sollte er sich aber schon erinnern (das gilt quasi für alle Softwaresysteme mit Benutzerauthentifizierung.
Tzwoenn (<- kann sich wieder nicht an sein pw erinnern)
Danke Tzwoenn. Aber wie komme ich bei diesem Verfahren an die Userdaten, wenn ich nicht der User bin, sondern ein Shopmitarbeiter, der wissen möchte, wo er eine Bestellung hinsenden soll?
Was man natürlich machen kann, ist die Daten, die der Kunde einträgt asymetrisch zu verschlüsseln, und den private key nicht auf eben diesem Server ablegen. Und wenn dann tatsächlich eine Bestellung erfolgt, werden die Daten an einen anderen Rechner geschickt, der sagen wir mal in einem geschützten Netz steht, von wo dann die Bestellung bearbeitet wird. Der public key ist nur auf diesem Rechner vorhanden und im optimalfall noch durch ein Passwort geschützt.
Nachteil ist halt, dass der Kunde seine eigenen Daten nicht mehr angezeigt bekommen kann. Aber z.B. für Kreditkartennummern fände ich das durchaus angebracht.
ich bin gerade ziemlich beeindruckt von diesen Ideen (vor allem weil ich sie sogar verstehe ;) ), aber prinzipiell fände ich es schonmal schön wenn allgemein die DB-Einträge IRGENDWIE verschlüsselt würden (also Kreditkartennr usw) … wie oft siehst man das bei riesigen Firmen, dass genau das nicht der Fall ist :(
Ansonsten einfach ne symmetrische Verschlüsselung mit generiertem Salt (wird beim Datensatz gespeichert) und Passwort (liegt in der Anwendung). Das ist zwar definitiv nicht sicher, sorgt aber zumindest dafür, dass man mit einemgeratenem Wert nicht alles auf einmal entschlüsseln kann.
tzwoenn (feierabend, juhu ^^ )
Passwort (liegt in der Anwendung)
Gut, das wäre meiner Meinung nach doch die einzige Möglichkeit. Ist ja prinzipiell ziemlich unnütz, besonders wenn man bedenkt, dass die Anwendung in PHP-Skripten vorliegt. Aber immerhin ist es eine winzige Hürde.
Ich finde schon, dass es ein relevanter Vorteil ist, wenn man die Kundendaten nicht einfach auslesen kann, sobald einem auf irgendeine Weise ein Datenbankdump in die Hände fällt. Die Hürde ist vielleicht klein, "winzig" würde ich aber nicht sagen.
Recht hast Du eigentlich.
Zumal man, wenn man irgendwo SQL einfügen und so die DB abziehen kann, ja nicht die Skripte mitbekommt…
Oder die Alternative: Nichts auf dem Server speichern.
Ich hab vor ner Weile auch einen kleinen Webshop gebastelt, der löst bei Bestellung eine Mail aus, auf dem Server bleiben keine Daten hängen.
Das bedeutet natürlich auch das der Kunde keinen Account oder sowas hat…