Sicherheit in eigener Anwendung...

Rund um die LCL und andere Komponenten
pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Sicherheit in eigener Anwendung...

Beitrag von pluto »

Hallo

da es bereits einige aktuelle Themen zum verschlüsseln gibt, wollte ich allgemein ein Thema Sicherheit und Umsetzung anfangen.

Ich habe ein Projekt, dass könnte in wenigen Wochen so weit sein, dass ich es nutzen kann.
Da ich ein Root-server gemietet habe, möchte ich das Programm dort laufen lassen.... Den Port werde ich mit iptabels extra absichern und auch geoblocking einbauen(so wie jetzt schon beim alten und beim neuen SSH Port). Das Programm wird also im "Wind" stehen...

Es ist ein einfacher Notizen Verwalter. Jede Notiz kann Unternotizen haben, aber diese können keine weiteren Unternotizen haben. Das Projekt habe ich Angefangen um auf der einen Seite Erfahrung zu sammeln in bereich Datenbanken und auf der anderen Seite wollte ich mich auch auf das User-Interface Konzentrieren und es sollte so einfach wie nur Möglich sein.

Das habe ich auch soweit geschafft. Ich setzte hier auf die MariaDB.
Beim Hinzufügen, Bearbeiten oder Löschen von Beiträgen setzte ich bereits auf "Prepared Statement". Bei Abfragen noch nicht(kommt aber noch).

Außerdem habe ich jetzt ein Rest-Server angefangen, als zwischen Ebene, zwischen User-Interface und Datenbank Anwendung.
Die Kommunikation zwischen Rest-Server und Client läuft inzwischen Verschlüsselt ab. Hierzu muss das apikeyfile auf dem Internet-server liegen und beim Client.

Als nächstes ist vorgesehen, einzelne Einträge in der DB zu verschlüsseln z.b. Meine Zugänge oder meine Termine. Hierbei Frage ich mich, wie ich das mit dem Password machen sollte. Z.b. dachte ich, ich erstelle mit der SHA1 methode ein Password Hash und transportiere ihn Verschlüsselt zum Server. Der Server Speichert jetzt das in sein Datei/Datenbank ab.
Somit kann im rest-Client eine Password Abfrage umgesetzt werden.

Jedoch besteht dann die Möglichkeit, dass Password durch einen Automaten zu Entschlüsseln... Allerdings alle Großen Projekte setzten es ganz ähnlich um. Z.B. Linux erzeugt eine Password Datei.

Der Rest-Client wird dann erst mal bei mir auf dem PC und auf mein Laptop laufen und wird ein Webserver sein.

Wie sieht ihr das? Wie würdet ihr sowas umsetzten?
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

Es gibt ein paar best practices:
1. verwende TLS, einfachste methode baue auf HTTP auf (z.B. baue ein CGI modul, sodass sich der webserver um den ganzen TLS kram kümmert). Das machst du wenn ich das aber richtig verstanden hab bereits mit der Rest schnittstelle
2. Hashe und Salte das passwort, am besten server und Clientseitig. Stabile hashes sind SHA256 oder für die paranoiden SHA512. Als als salt würde ich serverseitig eine 128bit zufallszahl verwenden, und Clientseitig einfach den Nutzernamen. Der Client sendet dann also SHA(User + Pass) an den sever, und der server speichert in der DB dann SHA(SHA(User + Pass) + Salt). Somit könnte auch jemand der deinen REST server infected keinen zugriff auf das PW haben
3. Verwende gute Zufallszahlen, unter POSIX/Linux /dev/urandom oder ansonsten cross plattform openSSL random

Jetzt ist die Frage, möchtest du eine End-Zu-End verschlüsselung haben (also das die Notizen verschlüsselt in der DB liegen oder nicht). Wenn du sie nicht brauchst sollte das oben schon reichen. Wenn nicht wirds etwas komplexer. Willst du das nur der ersteller die Notizen lesen kann, verschlüssel die Notizen einfach mit dem Nutzerpasswort (da das ja eh nur gehasht und gesaltet übertragen wird kann das keiner einsehen). Wenn du verschiedenen access willst von mehreren usern, ist es wohl am sinnvollsten für jede Gruppe eine gruppenpasswort zu generieren, was über authentifizierten schlüsseltausch (z.B. mit PGP) an alle parteien übertragen wird. das ist aber alles andere als einfach, und der grund warum es kaum end zu end verschlüsselte gruppenchats oder ähnliches gibt (immerhin muss bei design mit jedem neuen nutzer ein neues pw für die gesammte folgenden daten generiert werden)

Wenn ich das bauen wöllte, würde ich keine end zu end verschlüsselug implementieren, das backend als CGI Anwendung schreiben die XML daten an einen clienten sendet (HTTP clienten gehen auch recht einfach in lazarus zu implementieren). Eventuell, für accessability würde ich sogar das Frontend als Webseite schreiben (kann ja auch problemlos xml über HTTPs lesen, somit brauch ich nicht mal verschiedene interfaces).

Ich weiß nicht wie es aktuell mit Pas2JS aussieht, ob das bereits in der lage ist eine Solche anwendung zu handeln, ansonsten ist javascript und HTML auch nicht so sonderlich schwer

PS:
Beim Hinzufügen, Bearbeiten oder Löschen von Beiträgen setzte ich bereits auf "Prepared Statement". Bei Abfragen noch nicht(kommt aber noch).

ich würde von anfang an immer prepared statement verwenden, nicht das man es dann an einer kleinen stelle vergisst später zu ändern. eine Schwachstelle reicht schon aus damit dein gesammtes system zusammenfällt

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

1. verwende TLS, einfachste methode baue auf HTTP auf (z.B. baue ein CGI modul, sodass sich der webserver um den ganzen TLS kram kümmert). Das machst du wenn ich das aber richtig verstanden hab bereits mit der Rest schnittstelle

Genau, da ich noch keine Domain habe, kann ich noch kein Zertifikat beantragen. Ich habe versucht ein eigenes zu erstellen, dass war zwar auch Erfolgreich, aber Google-Chrome meckert natürlich...
Darum die Idee mit der Verschlüsselung. Für den Anfang. Später werde ich es auch noch ändern.

2. Hashe und Salte das passwort, am besten server und Clientseitig. Stabile hashes sind SHA256 oder für die paranoiden SHA512. Als als salt würde ich serverseitig eine 128bit zufallszahl verwenden, und Clientseitig einfach den Nutzernamen. Der Client sendet dann also SHA(User + Pass) an den sever, und der server speichert in der DB dann SHA(SHA(User + Pass) + Salt). Somit könnte auch jemand der deinen REST server infected keinen zugriff auf das PW haben

Das Password würdest du aber nur in der Datenbank speichern nicht als externe "Textdatei"? Im Prinzip währe es ja egal.
Das Keyfile welches ich gerade verwende hat ein zufalls Key von 1024 Zeichen. Wird aber noch nicht extra Verschlüsselt.


3. Verwende gute Zufallszahlen, unter POSIX/Linux /dev/urandom oder ansonsten cross plattform openSSL random

Guter Hinweis, kennst du Pascal Methoden um darauf zugreifen zu können? Zur Zeit mache ich es mir einfach, bin gerade nicht zuhause, aber heute Abend kann ich die Funktion zeigen, mit der ich das mache.

Jetzt ist die Frage, möchtest du eine End-Zu-End verschlüsselung haben (also das die Notizen verschlüsselt in der DB liegen oder nicht).

Ich möchte beides. D.H. ich möchte eine End-Zu-End Verschlüsslung haben, für den Transport und ich möchte einige Inhalte extra Verschlüsseln.

Wenn du sie nicht brauchst sollte das oben schon reichen. Wenn nicht wirds etwas komplexer. Willst du das nur der ersteller die Notizen lesen kann, verschlüssel die Notizen einfach mit dem Nutzerpasswort (da das ja eh nur gehasht und gesaltet übertragen wird kann das keiner einsehen).

Genau. Es soll nur die Person den Inhalt lesen können, wenn diese Person das Password kennt.

Wenn du verschiedenen access willst von mehreren usern, ist es wohl am sinnvollsten für jede Gruppe eine gruppenpasswort zu generieren, was über authentifizierten schlüsseltausch (z.B. mit PGP) an alle parteien übertragen wird. das ist aber alles andere als einfach, und der grund warum es kaum end zu end verschlüsselte gruppenchats oder ähnliches gibt (immerhin muss bei design mit jedem neuen nutzer ein neues pw für die gesammte folgenden daten generiert werden)

Das wäre für Später geplant aber in einem neuen Projekt/Variante.

Wenn ich das bauen wöllte, würde ich keine end zu end verschlüsselug implementieren, das backend als CGI Anwendung schreiben die XML daten an einen clienten sendet (HTTP clienten gehen auch recht einfach in lazarus zu implementieren)

Als CGI? Ich nutzte das Beispiel im fpc Wiki: LightHTTP oder so ähnlich.
Das habe ich erweitert.

Ich weiß nicht wie es aktuell mit Pas2JS aussieht, ob das bereits in der lage ist eine Solche anwendung zu handeln, ansonsten ist javascript und HTML auch nicht so sonderlich schwer

Genau. Jetzt verwende ich http://w2ui.com/web/demo, dass in reines JavaScript geschrieben. Außerdem verwende ich natürlich auch HTML und CSS.
Pass2JS wäre auch Nicht schlecht, muss ich mir mal anschauen... Aber ich bin mit der JavaScript Lib w2ui sehr zufrieden.... Wenn man es erst mal grob verstanden hat.

ich würde von anfang an immer prepared statement verwenden, nicht das man es dann an einer kleinen stelle vergisst später zu ändern. eine Schwachstelle reicht schon aus damit dein gesammtes system zusammenfällt

Guter Hinweis, ich habe es halt erst Später eingebaut... Aber am Anfang von diesem Projekt. Die Unit, kam vom Vorgänger Projekt.
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

Das Password würdest du aber nur in der Datenbank speichern nicht als externe "Textdatei"? Im Prinzip währe es ja egal.
Das Keyfile welches ich gerade verwende hat ein zufalls Key von 1024 Zeichen. Wird aber noch nicht extra Verschlüsselt.

Kannst du speichern wo du willst, da es gesaltet und gehasht ist brauchst du es auch nicht mehr im nachhinein zu verschlüsseln

Guter Hinweis, kennst du Pascal Methoden um darauf zugreifen zu können? Zur Zeit mache ich es mir einfach, bin gerade nicht zuhause, aber heute Abend kann ich die Funktion zeigen, mit der ich das mache.

DIe SSL funktionen gibts in der openssl unit, und /dev/urandom ist einfach eine "Datei" aus der man lesen kann
hier mal code von einem meiner CGI experimente

Code: Alles auswählen

//openssl:
uses openssl;
...
// generates a 32 Byte random number as Salt
function TLoginConnection.GenerateSalt: TSalt; // TSALT: 64 char string
var
  b: array[0..31] of byte;
begin
  // generate cryptographically secure byte string
  RAND_pseudo_bytes(@b[0], 32);
  // return as HEX string
  SetLength(Result, 64);
  BinToHex(@b[0], @Result[1], 32);
end;
 
// urandom:
function TLoginConnection.GenerateSalt: TSalt; // TSALT: 64 char string
var
  b: array[0..31] of byte;
begin
  // generate cryptographically secure byte string
  with TFilestream.create('/dev/urandom', fmopenread) do
  try
    read(b[0], 32);
  finally
    free;
  end;
  // return as HEX string
  SetLength(Result, 64);
  BinToHex(@b[0], @Result[1], 32);
end;
 


/dev/urandom ist zwar etwas lahm, aber wahrscheinlich die sicherste Zufallsquelle da es sich um echten Zufall handelt (da zur berechnung als seed interaktionen von hardware verwendet wird. selbst auf einem server ohne maus und tastatur die das seeden können, ist jede komponente im rechner physikalisch ein wenig anders, tickt um ein paar ns anders, versuchen zu unterschiedlichen zeiten interrupt zu senden, etc)

Genau. Es soll nur die Person den Inhalt lesen können, wenn diese Person das Password kennt.
...
Das wäre für Später geplant aber in einem neuen Projekt/Variante.

dann ganz einfach ein Rijandael (oder Twofish, oder Rijandael(TwoFish)) mit dem Passwort über die daten machen. Sollte sicher sein.

Als CGI? Ich nutzte das Beispiel im fpc Wiki: LightHTTP oder so ähnlich.
Das habe ich erweitert.

kenn ich nicht, ich verwende fpwebfür CGI, FastCGI und Server anwendungen
Kurze erklärung falls du es nicht kennst, CGI anwendungen sind anwendungen die über standard input ein HTTP request lesen, und über Standard output das ergebnis rausschreiben. Für jeden seitenraufruf wird also ein solcher prozess gestartet der sich darum kümmert. Ist an sich recht schnell und sollte für die meisten anwendungen kein Problem sein. Leider braucht Linux zum Starten eines Programmes c.a. 1 ms, das ist recht teuer bei sehr vielen anfragen. Daher gibt es FastCGI, da wird nur ein prozess gestartet, dem dann all die anfragen gesendet werden (der kann dann z.B. threads für die anfragen verweden). Hat den Vorteil das man nur so zu sagen einen minimalen server braucht und keinen vollständigen webserver, man sich gleichzeitig aber der Performance von nativem code ausnutzen kann. (Natürlch hat das noch andere vorteile, so kann man z.B. auch bash scripte als CGI anwendung verwenden)

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

Kannst du speichern wo du willst, da es gesaltet und gehasht ist brauchst du es auch nicht mehr im nachhinein zu verschlüsseln

Den Begriff "gesaltet" kenne ich noch nicht...

DIe SSL funktionen gibts in der openssl unit, und /dev/urandom ist einfach eine "Datei" aus der man lesen kann
hier mal code von einem meiner CGI experimente

Danke, werde ich mir mal ausprobieren, die Tage...

/dev/urandom ist zwar etwas lahm, aber wahrscheinlich die sicherste Zufallsquelle da es sich um echten Zufall handelt (da zur berechnung als seed interaktionen von hardware verwendet wird. selbst auf einem server ohne maus und tastatur die das seeden können, ist jede komponente im rechner physikalisch ein wenig anders, tickt um ein paar ns anders, versuchen zu unterschiedlichen zeiten interrupt zu senden, etc)

Ah, und die werden Laufend neu erzeugt vom Kernel? Darum sind sie auch immer anders zu jedem Zeitpunkt, wenn man liest?

dann ganz einfach ein Rijandael (oder Twofish, oder Rijandael(TwoFish)) mit dem Passwort über die daten machen. Sollte sicher sein.

Sehe ich auch so....

Kurze erklärung falls du es nicht kennst, CGI anwendungen sind anwendungen die über standard input ein HTTP request lesen, und über Standard output das ergebnis rausschreiben. Für jeden seitenraufruf wird also ein solcher prozess gestartet der sich darum kümmert.

Ah, ich kenne das ganze nur grob, habe es aber noch nie verwendet.
Ich nutzte halt das hier:
http://wiki.freepascal.org/Light_Web_Server
das habe ich wie gesagt, erweitert für meine zwecke...

Ist an sich recht schnell und sollte für die meisten anwendungen kein Problem sein. Leider braucht Linux zum Starten eines Programmes c.a. 1 ms, das ist recht teuer bei sehr vielen anfragen. Daher gibt es FastCGI, da wird nur ein prozess gestartet, dem dann all die anfragen gesendet werden (der kann dann z.B. threads für die anfragen verweden).

Die Idee ist auch nicht schlecht, so wäre aufjedenfall jede "Sitzung" in einem eigenen Container... wenn also etwas "schief" geht, gehen die anderen Verbindungen immer noch.

Hat den Vorteil das man nur so zu sagen einen minimalen server braucht und keinen vollständigen webserver, man sich gleichzeitig aber der Performance von nativem code ausnutzen kann. (Natürlch hat das noch andere vorteile, so kann man z.B. auch bash scripte als CGI anwendung verwenden)

Muss ich mal bei Gelegenheit ausprobieren.... Mir gefällt aber die Lösung mit fpc LightHttp sehr gut....
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

pluto hat geschrieben:Den Begriff "gesaltet" kenne ich noch nicht...

Wenn man passwörter gehasht speichert sind diese für sich eigentlich sicher. Ein problemchen ist allerdings wenn zwei leute das selbe Passwort haben hat man auch den selben hash. Das heißt zum einen man kann einfach sich von den bekannstesten Passwörtern die Hashes anschauen und sehen ob das passwort eins davon ist (was einfacher ist als für jedes Passwort einen SHA zu berechnen, SHA ist echt lahm), zum anderen gibt es bei vielen Services eine Hint funktion. Bei dem Adobe leak wurden Passwort Hashes, mit Nutzername und Hints geleaked, sodass man für oft vorkommende Passwörter praktisch ein Buch von Hinweisen hat. Um das zu vermeiden verwendet man Salts (vor dem hashen werden die daten gesalzen) der Salt wird im Klartext mit dem Passwort gespeichert, und muss nur bei allen Nutzern unterschiedlich sein. Als Passwort hash wird dann SHA(Salt + Passwort) gespeichert. Sodass keine zwei Nutzer mit dem selben Passwort den Selben hash haben.
Salten macht man für gewöhnlich auf der Server Seite (so muss der Client nicht dafür sorgen den Salt zu kennen, man kann ihn ganz entspannt in der DB auf dem server liegen lassen), dabei ist aber das Problem das der Client das Passwort an den Server senden muss (im klartext). Daher kann man doppelt salten, auf dem Clienten mit einem bekannten Salt (z.B. nuzername oder email) und auf dem Server (zufälliger salt). Der Serverseitige Salt sollte allerdings stark sein (z.B. 128 bit zuffalszahl) damit salt kollisionen unwahrscheinlich sind (emails oder nutzernamen sind normalerweise nicht sonderlich stark und sollen es ja auch nicht sein)

Ah, und die werden Laufend neu erzeugt vom Kernel? Darum sind sie auch immer anders zu jedem Zeitpunkt, wenn man liest?

Genau, der Kernel updated den zufallsseed (eine zahl aus der alle folgenden zufallszahlen die gelesen werden generiert werden) sehr häufig. Und da keine zwei Computersysteme sich gleichen (verarbeitungsqualität, außentemperatur, etc.) unterscheiden sich selbst identische Software läufe sehr stark, was praktisch echten Zufall bereitstellt.

Die Idee ist auch nicht schlecht, so wäre aufjedenfall jede "Sitzung" in einem eigenen Container... wenn also etwas "schief" geht, gehen die anderen Verbindungen immer noch.

CGI an sich ist toll, es ist simpel genug das man mit bash oder Python simple webseiten bauen kann, und überlässt das ganze parallelisieren etc. dem kernel. Man kann in andere Sessions nicht interferieren und muss sich über den ganzen threading kram, etc. keine gedanken machen.

Muss ich mal bei Gelegenheit ausprobieren.... Mir gefällt aber die Lösung mit fpc LightHttp sehr gut....


Ich hab dir mal eine minimalversion eines meiner projekte hier rangepackt, was fpweb verwendet. das gute daran ist, das projekt ist jetzt ein simpler http server zum lokalen testen, wenn ich es auf meinem server deployen will erstell ich einfach ein CGI projekt (lazweb package), füge die Units zum projekt, kompiliere als CGI und schmeiß sie grad auf meinem server ins NGNIX cgi Verzeichniss. Doof wirds erst ab ein paar tausend interaktionen aufeinmal, soviele nutzer hab ich aber bisher noch nicht gehabt

Das Beispiel besteht aus dem Login system mit salt und allem, sodass du dir mal anschauen kannst wie ich das gemacht hab. Ist auch halbwegs kommentiert. Hoffe es hilft. (Das projekt war aber dafür gedacht ausschließlich mit einem Clienten zu kommunizieren, und keinen HTML kram zu senden)

PS: das fpweb framework bietet auch die Möglichkeit HTML templates zu laden, mit placeholdern. Recht nett wenn man seinen html code nicht über Response.Add('<html>');
...
respose.Add('</html>');
im pascal code stehen haben möchte
Dateianhänge
Example.zip
(12.73 KiB) 81-mal heruntergeladen

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

, dabei ist aber das Problem das der Client das Passwort an den Server senden muss (im klartext). Daher kann man doppelt salten, auf dem Clienten mit einem bekannten Salt (z.B. nuzername oder email) und auf dem Server (zufälliger salt). Der Serverseitige Salt sollte allerdings stark sein (z.B. 128 bit zuffalszahl) damit salt kollisionen unwahrscheinlich sind (emails oder nutzernamen sind normalerweise nicht sonderlich stark und sollen es ja auch nicht sein)

Das mit den Password Senden im Klartext ist natürlich unschön, auch wenn man eine Transport Verschlüsslung hat.

CGI an sich ist toll, es ist simpel genug das man mit bash oder Python simple webseiten bauen kann, und überlässt das ganze parallelisieren etc. dem kernel. Man kann in andere Sessions nicht interferieren und muss sich über den ganzen threading kram, etc. keine gedanken machen.

Praktisch...

Doof wirds erst ab ein paar tausend interaktionen aufeinmal, soviele nutzer hab ich aber bisher noch nicht gehabt

Die muss man erst mal zusammen bekommen.... Für einfache kleinere Projekte sollte das mit CGI aufjedenfall gehen....

Das Beispiel besteht aus dem Login system mit salt und allem, sodass du dir mal anschauen kannst wie ich das gemacht hab. Ist auch halbwegs kommentiert. Hoffe es hilft. (Das projekt war aber dafür gedacht ausschließlich mit einem Clienten zu kommunizieren, und keinen HTML kram zu senden)

Prima, bestimmt Hilft...Danke...
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

Ich habe mir dein Beispiel angeschaut, wirklich gut geschrieben....

das Paket DCPcrypt habe ich bisher nur einmal verwenden und das liegt schon einige Jahre zurück.

Wenn ich das mit dem "Salt" richtig verstanden habe, ist das im Prinzip ein extra Token, der vor dem Password gesetzt wird Praktischerweise so:
SaltString+Password string und daraus wird dann ein Hash gebildet. In deinem Fall ein "SHA256Hash".
Das Problem dabei ist halt, wenn der SaltString verloren geht, nützt einen das Password auch nichts...

Die Idee ist aber nicht schlecht...Jeder User könnte im Prinzip sein eigenen SaltString haben oder jede Gruppe von Usern.

Das mit dem PasswordHint, meinst du damit sowas wie ein Hinweis, wenn man das Password vergessen hat?

Im Prinzip deckt deine aussage aber meine Annahmen...Das mit dem SaltString werde ich mal ausprobieren.... CGI habe ich bisher nicht verwenden, weil ich dachte in der Heutigen "Zeit" braucht man das nicht (mehr)... Das schöne ist natürlich, dass dann jede Verbindung in einem eigenen Container läuft, was die Sicherheit weiter erhöhen dürfte.

Wie sehen das andere? Bisher hat sich nur einer neben mir zu Wort gemeldet? Ich denke aber, dass wir nicht die einzinsten sind, die früher oder später vor diesem Problem standen oder stehen.
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

pluto hat geschrieben:Ich habe mir dein Beispiel angeschaut, wirklich gut geschrieben....

das Paket DCPcrypt habe ich bisher nur einmal verwenden und das liegt schon einige Jahre zurück.

Wenn ich das mit dem "Salt" richtig verstanden habe, ist das im Prinzip ein extra Token, der vor dem Password gesetzt wird Praktischerweise so:
SaltString+Password string und daraus wird dann ein Hash gebildet. In deinem Fall ein "SHA256Hash".
Das Problem dabei ist halt, wenn der SaltString verloren geht, nützt einen das Password auch nichts...

Die Idee ist aber nicht schlecht...Jeder User könnte im Prinzip sein eigenen SaltString haben oder jede Gruppe von Usern.

Das mit dem PasswordHint, meinst du damit sowas wie ein Hinweis, wenn man das Password vergessen hat?

Im Prinzip deckt deine aussage aber meine Annahmen...Das mit dem SaltString werde ich mal ausprobieren.... CGI habe ich bisher nicht verwenden, weil ich dachte in der Heutigen "Zeit" braucht man das nicht (mehr)... Das schöne ist natürlich, dass dann jede Verbindung in einem eigenen Container läuft, was die Sicherheit weiter erhöhen dürfte.

Wie sehen das andere? Bisher hat sich nur einer neben mir zu Wort gemeldet? Ich denke aber, dass wir nicht die einzinsten sind, die früher oder später vor diesem Problem standen oder stehen.


Genau, der Salt ist nicht geheim, und soll nur dafür sorgen das Passwörter ein bisschen verändert werden, sodass gleiche passwörter (und vor allem einfache passwörter) nicht den selben hash haben. Für gewöhlich steht der Serverseitige Salt einfach in der Nutzerdatenbank, der sollte komplex sein. Der Nutzerseite Salt muss ja mit etwas sein das der Nutzer/der Client kennt, da bietet sich der Nutzername an. Benutzernamen sind aber eher selten sonderlich zufällig, weshalb es sein kann das es bereits schon hashlisten mit den bekanntesten Nutzernamen und Passwort kombinationen gibt. Darum sollte man Serverseitig auf jeden fall einen Starken Salt verwenden. Gleichzeitig kann man Serverseitig garantieren, solang der Nutzereintrag in der DB vorhanden ist exsistiert der Salt auch noch. Einem Nutzer würde ich nicht zutrauen einen komplexen Salt zu speichern (immerhin wäre es echt doof wenn er die salt datei oder so verlieren würde und er sich nicht mehr anmelden könnte). Und wenn du es schaffen solltest deine Salts in der Datenbank zu verlieren, hast du weit aus schlimmere Probleme als das sich Leute nicht anmelden können.

Und ja mit Hints meine ich die Passwort Hinweise wie sie z.B. windows hat. Ohne salt sucht man sich dann einfach alle Passwörter mit gleichem hash raus und schaut dann in die Hints. z.B. wenn man als Hints hat: 1. Lieblingsmusiker 2. Rock'n'Roll legende und 3. 24.11.1991, muss man kein genie sein um drauf zu kommen das das passwort für all die Accounts freddie mercury ist. Deshalb war der Adobe Nutzerdaten Leak so verheerend.

Zu DCPCrypt, eigentlich bin ich kein großer Freund eine Bibliothek zu verwenden die seit 6 Jahren oder so nicht mehr weiter entwickelt wurde, grade bei Sicherheitskram, aber die SHA algorithmen sind so simpel das ich kaum glaube das da große Sicherheitslücken drin sind. Aber dennoch würde ich es heute wohl anders machen, da ich eh schon die Openssl für Zufall verwende würde ich da wohl einfach OpenSSl sha256 bzw Openssl evp hashes verwenden, das dürfte dann auch ganz ohne packages funktionieren (auch wenn ich nicht weiß ob die funktionen bereits in der OpenSSH unit sind). Generell bietet die openSSL eigentlich alles an Sicherheitsfunktionalität was man wohl je brauchen könnte, man muss sich dafür aber auch durch C dokumentation wälzen und versuchen das nach Pascal zu porten was man online findet. Ist zwar meist nicht schwer, aber zeitaufwendig

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

Ich habe gerade das Notizen Projekt neu angefangen mit neuen Schwerpunkten.
Einer davon ist nun die Sicherheit. Es geht auch darum das eine oder andere auszuprobieren.

Ich verwende jedoch im Gegensatz zur dir, eine TObjectList für die Liste von angemeldeten Nutzern. Fürs erste. Du verwendest eine eigene Table in der SQL Datenbank. Ich vermute das liegt an CGI. Da das ja einzelne Programme/Threads sind.

Ich habe mir noch mal dein Beispiel angeschaut. Das mit dem SHA256Hash(salt+password) habe ich eingebaut.

Dabei bin ich auch noch das mit dem Password im Klartext "Problem" gestolpert, dazu hast du dies geschrieben:

Salten macht man für gewöhnlich auf der Server Seite (so muss der Client nicht dafür sorgen den Salt zu kennen, man kann ihn ganz entspannt in der DB auf dem server liegen lassen), dabei ist aber das Problem das der Client das Passwort an den Server senden muss (im klartext). Daher kann man doppelt salten, auf dem Clienten mit einem bekannten Salt (z.B. nuzername oder email) und auf dem Server (zufälliger salt). Der Serverseitige Salt sollte allerdings stark sein (z.B. 128 bit zuffalszahl) damit salt kollisionen unwahrscheinlich sind (emails oder nutzernamen sind normalerweise nicht sonderlich stark und sollen es ja auch nicht sein)

Das verstehe ich jetzt noch nicht so genau. Ich erzeuge mit einer Funktion die ich aus deinem Beispiel habe ein Zufalls Salt.
Du schreibst jetzt hier, dass man dafür den Nutzer namen(auf der Clientseite) verwenden soll wie ist das genau zu verstehen?
Z.B.:
Benutzername + Password?

Ich muss das Password ja aufjedenfall im Klartext haben um es verwenden zu können in meinem LoginManager.
Ein Hash zu erzeugen geht so mit also nicht. Ich könnte es höchsten extra Verschlüsseln z.b. mit dem Benutzername (Password kennt der Server ja im Klartext nicht) so könnte der Server es wieder Entschlüsseln.
Dazu kommt noch die Transport Verschlüsslung. Doppelt hält besser...
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

pluto hat geschrieben:Das verstehe ich jetzt noch nicht so genau. Ich erzeuge mit einer Funktion die ich aus deinem Beispiel habe ein Zufalls Salt.
Du schreibst jetzt hier, dass man dafür den Nutzer namen(auf der Clientseite) verwenden soll wie ist das genau zu verstehen?
Z.B.:
Benutzername + Password?

Ich muss das Password ja aufjedenfall im Klartext haben um es verwenden zu können in meinem LoginManager.
Ein Hash zu erzeugen geht so mit also nicht. Ich könnte es höchsten extra Verschlüsseln z.b. mit dem Benutzername (Password kennt der Server ja im Klartext nicht) so könnte der Server es wieder Entschlüsseln.
Dazu kommt noch die Transport Verschlüsslung. Doppelt hält besser...


Die Idee ist wenn sich der Nutzer anmeldet sendet der Client Pass:=SHA256(UserName + Passwort) zusammen mit dem Nutzernamen. Der Server schaut dann in die Datenbank, liest das Salt von dem Nutzernamen und Berechnet SAH256(Salt + Pass), und vergleicht dann ob das mit dem Hash in der Datenbank übereinstimmt. Falls ja ist man eingeloggt. Ab diesem punkt verwendest du einen Cookie/Login Token, welches irgendwann ausläuft wenn man sich nicht regelmäßig wieder meldet (auch in meinem Beispiel) und ab diesem punkt siehst du das passwort/den gesalteten hash nie wieder und alle authentifizierung geht über das Login Token. Durch das Hashen und Salten auf der Clientseite bekommt der Server nie das echte Passwort zu gesicht. Selbst wenn also jemand deinen Server infizieren würde hätte er nie eine chance an das passwort zu kommen. Der Server verhält sich also so als wäre SHA256(Username + Passwort) das eigentliche passwort

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

Die Idee ist wenn sich der Nutzer anmeldet sendet der Client Pass:=SHA256(UserName + Passwort)

Als Beispiel
Pass:=SHA256('Pluto .MeinPassword.');
Der Server kennt jetzt nur den Benutzernamen, dass Password im Klartext kennt der Server aber gar nicht.

Der Server schaut dann in die Datenbank, liest das Salt von dem Nutzernamen und Berechnet SAH256(Salt + Pass), und vergleicht dann ob das mit dem Hash in der Datenbank übereinstimmt.

Diesen Teil mache ich bereits. Was ich jedoch noch nicht verstehe ist wie das Von oben mit dem hier zusammen gehört?
Im Prinzip müsste ich das Password in der DB genau so ablegen also:
SHA256(Salt+Benutzernamen+Password).

Aber du schreibst jetzt "SAH256(Salt + Pass)"....
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

pluto hat geschrieben:Diesen Teil mache ich bereits. Was ich jedoch noch nicht verstehe ist wie das Von oben mit dem hier zusammen gehört?
Im Prinzip müsste ich das Password in der DB genau so ablegen also:
SHA256(Salt+Benutzernamen+Password).

Aber du schreibst jetzt "SAH256(Salt + Pass)"....


Pass ist das was der Client als passwort sendet also steht da eigentlich SHA256(Salt + SHA256(Username + Password)). Wobei der Server ja nicht weiß was Password ist, da er SHA256(Username + Password) ja vom user gesendet bekommt. Der server wird also genauso implementiert wie wenn der Client nicht salten würde und behandelt das was der client ihm gibt als login passwort.

PS: bei sowas ist es auch immer hilfreich zu schauen wie andere, experten, das ganze implementieren. Hier ist ein whitepaper von Dashlane, einem Cloud Passwort manager, dem nachgesagt wird sehr sicher zu sein. Die gehen sogar noch einen schritt weiter, die verschlüsseln die Userdaten auch mit dem Passwort, und statt das Passwort irgendwo zu speichern benutzen sie das passwort um die Nutzerdaten zu entschlüsseln, und falls das erfolgreich war ist man eingeloggt. Somit kann man selbst wenn man zugriff auf die Datenbank von ihnen hätte nicht mal die Passwörter effizient bruteforcen, da das entschlüsseln von daten viel rechenaufwendiger ist als das bilden von Hashes. (Es stört mich grade etwas das ich nicht von selbst auf die Idee gekommen bin, die ist echt gut). Die einzige möglichkeit dann an das Passwort/den Hash zu kommen ist wenn man zufällig während dem login zugriff auf die Prozessmemory hat.

Edit: hab das bei Dashlane doch falsch verstanden, man registriert sich mit einem Device key, welchen man verschlüsselt auf dem Gerät haben muss mit dem man sich anmeldet und Geräte kann man mit einem Email oder SMS one time passwort registrieren. Das kann man natürlich bei einer Browseranwendung schlecht machen.

Auch noch ein bisschen Infos wie LastPass die Security handelt: Link
Zuletzt geändert von Warf am Do 20. Dez 2018, 00:45, insgesamt 1-mal geändert.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Sicherheit in eigener Anwendung...

Beitrag von pluto »

Pass ist das was der Client als passwort sendet also steht da eigentlich SHA256(Salt + SHA256(Username + Password)). Wobei der Server ja nicht weiß was Password ist, da er SHA256(Username + Password) ja vom user gesendet bekommt. Der server wird also genauso implementiert wie wenn der Client nicht salten würde und behandelt das was der client ihm gibt als login passwort.

OK, so ergibt es einen Sinn. Also wird hier doppelt gehasht wenn man so möchte.

Die gehen sogar noch einen schritt weiter, die verschlüsseln die Userdaten auch mit dem Passwort, und statt das Passwort irgendwo zu speichern benutzen sie das passwort um die Nutzerdaten zu entschlüsseln, und falls das erfolgreich war ist man eingeloggt.

(Es stört mich grade etwas das ich nicht von selbst auf die Idee gekommen bin, die ist echt gut)


Die Idee hatte ich auch schon. Nur: wenn man das Password ändern möchte, muss man alles einmal entschlüsseln um es dann erneut zu verschlüsseln. Bei mehren Notizen und Benutzern eigentlich keine gute Idee oder?
Aber die Idee hat was...
Ich denke es gibt viele Wege. eine Idee wäre ein zweites Password zu verwenden: eins um sich anzumelden und eins oder mehrer für die eigentlichen Daten... ich denke das kann man auf die Spitze treiben wenn man möchte.
MFG
Michael Springwald

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sicherheit in eigener Anwendung...

Beitrag von Warf »

Schau mal oben, ich hab meinen Post editiert, ich hab das bei Dashlane falsch verstanden, die machen genau das. Aber um das neuverschlüsseln beim Passwort wechsel wirst du wohl oder übel nicht herum kommen können. Das Passwort möchte man doch eher ändern als das login passwort. Das ist immerhin ohne das entschlüsselpasswort nutzlos

Antworten