Dateien in DB verschlüsselt ablegen und wieder abrufen
Andreas
- programmiertechnik
Hallo,
ich wusste nicht genau unter welche Rubrik ich diesen Thread aufmachen sollte, doch Programmiertechnik hielt ich für passend.
Ich möchte auf meinem lokalen Rechner einige Dateien verschlüsselt ablegen. Das ganze kann man zwar mit einer verschlüsselten Partition erledigen, doch ich möchte zusätzlich auch zu jeder Datei einige Kommentare hinzufügen, um später danach suchen zu können (so wie bei "Beagle" bzw. für Mac "Spotlight"). Angedacht ist als DB mysql und serverseitige Skriptspache PHP5 ggf. JSP/Servlets.
Meine Überlegung ist es nun, die Dateien per HTML-Formular übertragen, als BLOB abspeichern und mit "ENCODE" zu verschlüsseln. Die Zuordnung von Kommentaren zu jeder Datei ist dann ja auch nicht weiter schwierig. Beim Abrufen der gewünschten Dateien in lesbarer Form ist per DECODE ja wieder möglich.
Die unverschlüsselten Dateien vor dem Upload bzw. nach dem Download kann ich ja per shred vor Wiederherstellungsversuchen relativ gut absichern, so dass meist nur noch die verschlüsselten Dateien auf dem Rechner sind. Das shredden könnte man ja evtl. auch automatisieren.
Ich weiss das es nicht so der Hit sein soll Dateien in die DB abzulegen, doch ich denke für den lokalen Einsatz und den paar Dokumenten sollte das nicht so größeren Problemen führen.
Zu diesen Überlegungen würde ich gern Eure Meinung und vor allem auch Verbesserungsvorschläge sowie Sicherheitsbedenken lesen. Ich freue mich auf eine lebhafte Diskussion.
Viele Grüße
Andreas
Hallo Andreas,
ich finde deinen Plan interessant, kann aber nicht wirklich was sinnvolles beitragen. Dass du eine SSL Verbindung brauchst, um die Dateien per HTML Formular zu übertragen ist dir sicherlich auch klar. Und du meinst auch sicherlich dass du von Außen auf diese Weise die Daten auf deinen Rechner übertragen willst und nicht nur lokal...denn sonst warum überhaupt das HTML Formular.
Vielleicht ist es noch eine Überlegung Wert die Dateien nicht in die Datenbank zu schreiben, sondern verschlüsselt im Filesystem abzulegen. In der Datenbank brauchst du dann nur Pfad/Filename zu speichern, was ja eindeutig ist, und natürlich die Metaangaben dazu, die du ja wolltest. Auf diese Weise entlastest du die Datenbank von 99,9% der Datenmenge und nutzt sie wirklich nur dafür wofür sie da ist: schnell etwas zu suchen.
Ciao,
Cruz
Hallo,
ich wusste nicht genau unter welche Rubrik ich diesen Thread aufmachen sollte, doch Programmiertechnik hielt ich für passend.
Ich möchte auf meinem lokalen Rechner einige Dateien verschlüsselt ablegen. Das ganze kann man zwar mit einer verschlüsselten Partition erledigen, doch ich möchte zusätzlich auch zu jeder Datei einige Kommentare hinzufügen, um später danach suchen zu können (so wie bei "Beagle" bzw. für Mac "Spotlight"). Angedacht ist als DB mysql und serverseitige Skriptspache PHP5 ggf. JSP/Servlets.
Meine Überlegung ist es nun, die Dateien per HTML-Formular übertragen, als BLOB abspeichern und mit "ENCODE" zu verschlüsseln. Die Zuordnung von Kommentaren zu jeder Datei ist dann ja auch nicht weiter schwierig. Beim Abrufen der gewünschten Dateien in lesbarer Form ist per DECODE ja wieder möglich.
Die unverschlüsselten Dateien vor dem Upload bzw. nach dem Download kann ich ja per shred vor Wiederherstellungsversuchen relativ gut absichern, so dass meist nur noch die verschlüsselten Dateien auf dem Rechner sind. Das shredden könnte man ja evtl. auch automatisieren.
Ich weiss das es nicht so der Hit sein soll Dateien in die DB abzulegen, doch ich denke für den lokalen Einsatz und den paar Dokumenten sollte das nicht so größeren Problemen führen.
Zu diesen Überlegungen würde ich gern Eure Meinung und vor allem auch Verbesserungsvorschläge sowie Sicherheitsbedenken lesen. Ich freue mich auf eine lebhafte Diskussion.
Viele Grüße
Andreas
Hallo,
erst einmal danke für Dein Antwort.
Und du meinst auch sicherlich dass du von Außen auf diese Weise die Daten auf deinen Rechner übertragen willst und nicht nur lokal...
Nein, lokal reicht mir da aus.
Vielleicht ist es noch eine Überlegung Wert die Dateien nicht in die Datenbank zu schreiben, sondern verschlüsselt im Filesystem abzulegen. In der Datenbank brauchst du dann nur Pfad/Filename zu speichern, was ja eindeutig ist, und natürlich die Metaangaben dazu, die du ja wolltest. Auf diese Weise entlastest du die Datenbank von 99,9% der Datenmenge und nutzt sie wirklich nur dafür wofür sie da ist: schnell etwas zu suchen.
Die Geschwindigkeit ist mir da nicht so wichtig. Außerdem suche ich dann später in erster Linie in den varchar Spalten, welche die Metaangaben beinhalten und nicht in den großen BLOBs. Und bei dem Ablegen der Dateien im Dateisystem stellt sich wieder die Frage nach der Transaktionssicherheit. Ist in diesem Fall jedoch nicht so relevant.
Viele Grüße
Andreas
Hallo Andreas,
erst einmal danke für Dein Antwort.
Immer gerne.
Und du meinst auch sicherlich dass du von Außen auf diese Weise die Daten auf deinen Rechner übertragen willst und nicht nur lokal...
Nein, lokal reicht mir da aus.
Dann kann ich allerdings deine Entscheidung für das HTML Formular nicht nachvollziehen. Vielleicht hast du noch nicht alles erzählt, was du mit dieser File-Datenbank machen möchtest. Ein HTML Frontend eignet sich dann besonders gut, wenn du die Absicht hast die Software aus dem Internet oder zumindest aus einem LAN zu nutzen. Für eine Einzelstationsanwendung eignet sich HTML in MHO nicht besonders gut, da man z.B. die ganzen Schwächen des stateless HTTP Protokolls bekämpfen muss.
Schon alleine der Upload ist ein Umweg von hinten durch die Nase ins Auge. Die Datei muss über ein Klartextprotokoll codiert werden und wird auch noch mit Zeug drum herum eingepackt (Header und so ein Kram) nur um dann später wieder ausgepackt, decodiert und in die Datenbank geschrieben zu werden. Der direkte Weg ohne HTTP dazwischen ist kürzer und einfacher.
Gut, wenn du nun mal hauptsächlich die Internet Technologie mit HTML und PHP beherrschst, dann kann ich es verstehen, aber du hast doch was von Servlets und JSP gesagt. Also wenn du Java kannst, warum schreibst du dir nicht lieber ein Java Programm von mir aus mit einem Swing oder AWT Frontend. Oder wenn du Visual Basic oder sowas kannst, kannst du damit am schnellsten für Windows eine Anwendung basteln (obwohl ich persönlich den Kram niemals anfassen würde).
Die Geschwindigkeit ist mir da nicht so wichtig. Außerdem suche ich dann später in erster Linie in den varchar Spalten, welche die Metaangaben beinhalten und nicht in den großen BLOBs.
Ich kann leider keine qualifizierte Aussage dazu treffen, wie genau sich die Datenmenge in der Blob Spalte auf die Performance der Datenbank auswirkt, es ist nur ein Gefühl von mir, dass dann in der Datenbank hauptsächlich Daten stehen, die da nichts verloren haben und das wird sicherlich irgendwelche negativen Effekte mit sich bringen.
Und bei dem Ablegen der Dateien im Dateisystem stellt sich wieder die Frage nach der Transaktionssicherheit. Ist in diesem Fall jedoch nicht so relevant.
Hm Transaktionssicherheit? Ok was bedeutet das eigentlich genau? Meines Wissens nach ist eine Art alles oder nichts Verhalten, also mehrere zusammenhängende Datensätze werden nur in ihrer Gesamtheit geschrieben bzw. gelöscht, die Datenbank macht keine halben sachen.
Und du kannst einen Rollback machen. Solange du nur eine Tabelle hast, kannst du mit Transaktionssicherheit nichts anfangen.
Außerdem bin ich mir nicht sicher, ob die aktuelle MySQL Version überhaupt Transaktionen unterstützt. Ich weiß das stand mal auf deren Todo Liste, kann aber nicht sagen ob die das schon umgesetzt haben. Ach...du wolltest doch MySQL nehmen gell?
Und vielleicht noch als Schlußbemerkung:
Wenn du die Files in die Datenbank schreibst, dann sind sie auch von der Datenbank abhängig, denn du kommst nicht an die Dateien dran ohne die Datenbank zu konsultieren. Was ist wenn das gerade mal aus irgendwelchen Gründen nicht geht, aber du willst schnell mal an eine Datei ran? Oder bedenke wie es ausschaut, wenn du die Datenbank administrierst und z.B. über einen Dump die Daten verschieben willst. Dann stehen die ganzen verschlüsselten Files in einer riesigen Textdatei, das ist doch irgendwie krumm. Oder wie realisierst du einen Backup? Sind die verschlü. Files im Filesystem, stehen dir alle Backuptechnologien der Welt zur Verfügung. Sind die Files in der Datenbank, musst du sie entweder erst dumpen und dann sind wir wieder bei der schrägen Textdatei, oder du musst halt die ganze Datenbank auf Filesystemebene backupen und verschwendest damit Platz.
So jetzt habe ich also ganz klar die Position "Files ins Filesystem" bezogen und ein paar Argumente gebracht, würde aber allerdings gerne auch Argumente für die Gegenseite hören. Auch wenn das jetzt keine mission critical Anwendung werden soll, macht es doch Spaß sich die Pros und Kontras zu überlegen. Ich will dich auch nicht beim brechen und biegen davon abbringen die Files in die DB zu schreiben, ich bin eher an der Diskussion interessiert. :)
Gruß,
Cruz
Hallo Cruz,
Dann kann ich allerdings deine Entscheidung für das HTML Formular nicht nachvollziehen. Vielleicht hast du noch nicht alles erzählt, was du mit dieser File-Datenbank machen möchtest. Ein HTML Frontend eignet sich dann besonders gut, wenn du die Absicht hast die Software aus dem Internet oder zumindest aus einem LAN zu nutzen. Für eine Einzelstationsanwendung eignet sich HTML in MHO nicht besonders gut, da man z.B. die ganzen Schwächen des stateless HTTP Protokolls bekämpfen muss.
Stimmt auch wieder. Was ich mir halt dazu noch basteln möchte ist ein Frontend, so dass ich lokal per Browser die Dateien auch verwalten, suchen und abrufen kann.
Schon alleine der Upload ist ein Umweg von hinten durch die Nase ins Auge. Die Datei muss über ein Klartextprotokoll codiert werden und wird auch noch mit Zeug drum herum eingepackt (Header und so ein Kram) nur um dann später wieder ausgepackt, decodiert und in die Datenbank geschrieben zu werden. Der direkte Weg ohne HTTP dazwischen ist kürzer und einfacher.
Da dies sowieso nur lokal läuft, sehe ich die Übertragung im Klartext nicht schlimm an. Aber ist sicher ein Argument.
Hm Transaktionssicherheit? Ok was bedeutet das eigentlich genau? Meines Wissens nach ist eine Art alles oder nichts Verhalten, also mehrere zusammenhängende Datensätze werden nur in ihrer Gesamtheit geschrieben bzw. gelöscht, die Datenbank macht keine halben sachen.
Genau. Mit den InnoDB Tabellentypen geht das zum Beispiel auch. Ich glaube diesen Tabellentyp gibt es schon relativ lange.
Außerdem muss ich so nur überprüfen, ob die insert´s alle korrekt ausgeführt wurden und muss mich nicht darum kümmern, ob auch die Datei im Filesystem gelandet ist, falls ich alles in die DB ablege.
Und du kannst einen Rollback machen. Solange du nur eine Tabelle hast, kannst du mit Transaktionssicherheit nichts anfangen.
Es gibt ja noch eine Tabelle mit den Metaangaben (id,metaangabe), sowie eine Tabelle für die Zuordnung "Metaangabe zur Datei" (metangabe_id,datei_id). Daher macht das schon etwas Sinn mit der Transaktionsicherheit. Ok, ich gebe zu: Als lokale Einzelanwendung sicher etwas übertrieben ;-)
Wenn du die Files in die Datenbank schreibst, dann sind sie auch von der Datenbank abhängig, denn du kommst nicht an die Dateien dran ohne die Datenbank zu konsultieren. Was ist wenn das gerade mal aus irgendwelchen Gründen nicht geht, aber du willst schnell mal an eine Datei ran? Oder bedenke wie es ausschaut, wenn du die Datenbank administrierst und z.B. über einen Dump die Daten verschieben willst. Dann stehen die ganzen verschlüsselten Files in einer riesigen Textdatei, das ist doch irgendwie krumm. Oder wie realisierst du einen Backup? Sind die verschlü. Files im Filesystem, stehen dir alle Backuptechnologien der Welt zur Verfügung. Sind die Files in der Datenbank, musst du sie entweder erst dumpen und dann sind wir wieder bei der schrägen Textdatei, oder du musst halt die ganze Datenbank auf Filesystemebene backupen und verschwendest damit Platz.
Ich sichere (fast) täglich die relevanten Daten vom Rechner. Dazu gehören unter anderem auch alle Datenbanken und das htdocs Verzeichnis. Also das ist nicht weiter problematisch und erfordert keinen weiteren Aufwand. Und so groß werden die Daten auch nicht. Vornehmlich sollen da einige wenige private Dokumente abgespeichert werden. So wie es aussieht wird kaum eine Datei größer als 1MB groß.
So jetzt habe ich also ganz klar die Position "Files ins Filesystem" bezogen und ein paar Argumente gebracht, würde aber allerdings gerne auch Argumente für die Gegenseite hören. Auch wenn das jetzt keine mission critical Anwendung werden soll, macht es doch Spaß sich die Pros und Kontras zu überlegen. Ich will dich auch nicht beim brechen und biegen davon abbringen die Files in die DB zu schreiben, ich bin eher an der Diskussion interessiert. :)
Ich ebenso :-) Und wie gesagt ist es eh für den privaten Einsatz gedacht. Und was mir auch wichtig ist, wie "sicher" man dieses Vorhaben umsetzen kann. Da weiss ich leider nicht genau Bescheid, ob das mySQL DECODE hinreichend sicher ist und was man anschließend shredden sollte.
Viele Grüße
Andreas
Hallo Andreas,
Und wie gesagt ist es eh für den privaten Einsatz gedacht.
Das hält uns aber doch nicht davon ab darüber nachzudenken wie man es in einem größerem Rahmen angehen würde oder? :) Und was für einen größeren Rahmen gut genug ist, das muss für deine Home-Applikation erst recht gut sein.
Schon alleine der Upload ist ein Umweg von hinten durch die Nase ins Auge. Der direkte Weg ohne HTTP dazwischen ist kürzer und einfacher.
Da dies sowieso nur lokal läuft, sehe ich die Übertragung im Klartext nicht schlimm an.
Ich meine damit nicht die Übertragungszeit, sondern dass es unterwegs eine Menge Dinge, die schiefgehen können. Wenn du die Dateien auf einem direkterem Weg einliest, elimierst du Fehlerquellen.
Außerdem muss ich so nur überprüfen, ob die insert´s alle korrekt ausgeführt wurden und muss mich nicht darum kümmern, ob auch die Datei im Filesystem gelandet ist, falls ich alles in die DB ablege.
Du bist ja hart drauf. Checks machen eine Software langsamer. Alles was von einem User eingegeben wird muss auf Herz und Nieren geprüft werden, aber ein INSERT in die DB oder eine Schreiboperation ins Filesystem würde ich nicht mehr überprüfen, wenn sie ohne Fehlermeldung durchgelaufen ist.
Es gibt ja noch eine Tabelle mit den Metaangaben (id,metaangabe), sowie eine Tabelle für die Zuordnung "Metaangabe zur Datei" (metangabe_id,datei_id).
Hm..ich würde das in einer Tabelle machen, weil es nur eine 1:1 Relation ist.
Deine Version:
id, metaangabe, blob mit encoded file
Meine Version:
id, metaangabe, pfadangabe zum encoded file
Ich sichere (fast) täglich die relevanten Daten vom Rechner. Dazu gehören unter anderem auch alle Datenbanken und das htdocs Verzeichnis.
Ja wie sicherst du denn eine Datenbank? Klar zu Hause mit ein paar MBs brauchst du dir keine Gedanken machen, aber wir spielen ja großen Rahmen. Eine Datenbank mit "Haut und Haaren" zu backupen ist keine gute Idee, denn dan sichert man auch die Datenbank Programme, die Manuals und die Logfiles mit. Normalerweise ist ein Backup auf Platzersparnis optimiert und da haben solche Dinge nichts verloren, nur die reinen möglichst gut komprimierten Daten.
Und was mir auch wichtig ist, wie "sicher" man dieses Vorhaben umsetzen kann. Da weiss ich leider nicht genau Bescheid, ob das mySQL DECODE hinreichend sicher ist und was man anschließend shredden sollte.
Klar hilft das shredden, nachdem du die Datei in die DB geschrieben und vom Filesystem gelöscht hast. Und das ENCODE ist sehr sicher was
das dekodieren mit einer Brute Force Attacke angeht. Aber mal angenommen ich breche in deinem System ein. Ich würde als erstes in deinem Quelltext nach dem Passwort suchen, was du für das ENCODE verwendest und schon habe ich deine Daten. User und Passwort für die Datenbank stehen wahrscheinlich sogar in einer leicht zu findenen Konfig Datei.
Viel sicherer finde ich folgende Methode:
Wenn du eine neue Datei einpflegen willst, dann schreibst du sie ins Filesystem und verschlüsselst sie mit einem Passwort, dass du nur zum Zeitpunkt der Verschlüsselung eingibst. Dieses Passwort steht nirgends auf deinem Computer gespeichert, es existiert nur in deinem Kopf und ist höchstens mit altertümlichen Foltermethoden zu erlangen. Dann trägst du die Metaangaben + den Pfad zur Datei in die Datenbank ein und fertig. Jetzt sehe ich keine Möglichkeit mehr an deine Daten zu gelangen, wenn ich bei dir einbreche. Ich könnte bestenfalls deine Metaangaben dazu lesen. Und das shredden wird nebenbei auch komplett überflüssig.
Gruß,
Cruz
Hallo Cruz,
Und wie gesagt ist es eh für den privaten Einsatz gedacht.
Das hält uns aber doch nicht davon ab darüber nachzudenken wie man es in einem größerem Rahmen angehen würde oder? :) Und was für einen größeren Rahmen gut genug ist, das muss für deine Home-Applikation erst recht gut sein.
Stimmt schon. Aber übertreiben wollte ich es auch nicht ;-) Doch die Gedanken für den größeren Einsatz sind durchaus interessant.
Ich meine damit nicht die Übertragungszeit, sondern dass es unterwegs eine Menge Dinge, die schiefgehen können. Wenn du die Dateien auf einem direkterem Weg einliest, elimierst du Fehlerquellen.
Ich könnte auch ein upload Ordner einrichten und die Dateien dorthin verschieben und anschließend im Frontend eine Auswahlliste generieren lassen aus der ich die zu verschlüsselnden Dateien auswähle. So erspare ich mir das upload Formular und die damit einhergehenden Sicherheitsprobleme. Die verschlüsselnden Dateien werden dann in einen secure-Ordner verschoben. Beim decodieren dann in einen download-Ordner, in dem manuell wieder die Dateien geschreddet werden können, sobald die Datei nicht mehr gelesen werden soll.
Außerdem muss ich so nur überprüfen, ob die insert´s alle korrekt ausgeführt wurden und muss mich nicht darum kümmern, ob auch die Datei im Filesystem gelandet ist, falls ich alles in die DB ablege.
Du bist ja hart drauf. Checks machen eine Software langsamer. Alles was von einem User eingegeben wird muss auf Herz und Nieren geprüft werden, aber ein INSERT in die DB oder eine Schreiboperation ins Filesystem würde ich nicht mehr überprüfen, wenn sie ohne Fehlermeldung durchgelaufen ist.
Da möchte ich nur Fehlerquellen vermeiden. Und ein COMMIT, ROLLBACK oder auch LOCK table zusätzlich in den SQL Abfragen sind auch nicht so der große Aufwand.
Hm..ich würde das in einer Tabelle machen, weil es nur eine 1:1 Relation ist.
Meine Version:
id, metaangabe, pfadangabe zum encoded file
Würde auch gehen. Wenn man auf die Spalte metangabe noch einen Volltextindex legt, kann man mit MATCH AGAINST auch gut suchen lassen.
Ja wie sicherst du denn eine Datenbank? Klar zu Hause mit ein paar MBs brauchst du dir keine Gedanken machen, aber wir spielen ja großen Rahmen. Eine Datenbank mit "Haut und Haaren" zu backupen ist keine gute Idee, denn dan sichert man auch die Datenbank Programme, die Manuals und die Logfiles mit. Normalerweise ist ein Backup auf Platzersparnis optimiert und da haben solche Dinge nichts verloren, nur die reinen möglichst gut komprimierten Daten.
Ich sicher die einfach mit mysqldump, also wird nur das gesichert was ich brauche. Also keine Logfiles etc. Die Sicherung wird auch nur dann erstellt, wenn keine Datenbank Zugriffe/Schreiboperationen ausgeführt werden.
Klar hilft das shredden, nachdem du die Datei in die DB geschrieben und vom Filesystem gelöscht hast. Und das ENCODE ist sehr sicher was
das dekodieren mit einer Brute Force Attacke angeht. Aber mal angenommen ich breche in deinem System ein. Ich würde als erstes in deinem Quelltext nach dem Passwort suchen, was du für das ENCODE verwendest und schon habe ich deine Daten. User und Passwort für die Datenbank stehen wahrscheinlich sogar in einer leicht zu findenen Konfig Datei.
Nein, das Passwort würde ich erst über das Webfrontend eingeben und in der Session speichern. Das Passwort kann ich ggf. auch in der Datenbank speichern und mit PASSWORD() verschlüsseln. Beim einloggen wird überprüft, ob das Passwort stimmt. Falls ja, wird dieser String bis zum Ausloggen in der Session gespeichert und zum decodieren genutzt. Also liegt nirgends das Passwort im Klartext vor.
Wenn du eine neue Datei einpflegen willst, dann schreibst du sie ins Filesystem und verschlüsselst sie mit einem Passwort, dass du nur zum Zeitpunkt der Verschlüsselung eingibst. Dieses Passwort steht nirgends auf deinem Computer gespeichert, es existiert nur in deinem Kopf und ist höchstens mit altertümlichen Foltermethoden zu erlangen. Dann trägst du die Metaangaben + den Pfad zur Datei in die Datenbank ein und fertig. Jetzt sehe ich keine Möglichkeit mehr an deine Daten zu gelangen, wenn ich bei dir einbreche. Ich könnte bestenfalls deine Metaangaben dazu lesen. Und das shredden wird nebenbei auch komplett überflüssig.
Da weiss ich leider nicht ausreichend Bescheid, ob das shredden wirklich nicht notwendig ist. Evtl. wird beim verschlüsseln (egal ob mit encode oder einem verschlüsseltem Dateisystem) doch irgendwo eine unverschlüsselte Kopie angelegt, die zwar gelöscht wird aber mit diversen Tools doch zu restaurieren geht.
Da sehe ich noch Probleme: Ich habe vielleicht wunderbar die Dateien verschlüsselt, die ohne Passwort nicht zu decodieren sind (außer mit Brute Force), aber irgendwo liegen dann doch noch -für den normal Benutzer unsichtbar- die Dateien im Dateisystem. Mit diversen Tools kann man das ja wiederherstellen. Also suche ich noch eine Möglichkeit alle Dateien die gelöscht wurden auch zu shredden.
Viele Grüße
Andreas