User Daten (Passwort etc.) sicher aufbewahren

jb_alvarado

Lt. Junior Grade
Registriert
Sep. 2015
Beiträge
492
Hallo Leute,
ich wollte mich mal an einem kleinen Desktop App versuchen. Das ganze möchte ich mit Rust/Tauri umsetzten und damit kimai ansteuern.

Dazu müsste ich Benutzer und API Password irgendwo sicher speichern. Der Einfachheit halber würde ich das in einer sqlite DB machen. Ist etwas overdose, weil ich nur zwei Tabellen brauche, mit jeweils nur einer Spalte, aber was besseres ist mir noch nicht eingefallen. Verschlüsseln würde ich das Passwort mit argon2, allerdings braucht es dazu einen secret key. Jetzt frage ich mich gerade wie man diesen secret key sicher aufbewahrt. Wenn ich ihn im Source Code habe und der Code zugängig ist, bringt das Verschlüsseln ja auch nicht viel, oder?

Was ist denn hier die gängige Praxis?
 
jb_alvarado schrieb:
Der Einfachheit halber würde ich das in einer sqlite DB machen. Ist etwas overdose, weil ich nur zwei Tabellen brauche, mit jeweils nur einer Spalte, aber was besseres ist mir noch nicht eingefallen.
Einfach in einer Textdatei ablegen? Oder binär.

jb_alvarado schrieb:
Verschlüsseln würde ich das Passwort mit argon2, allerdings braucht es dazu einen secret key. Jetzt frage ich mich gerade wie man diesen secret key sicher aufbewahrt. Wenn ich ihn im Source Code habe und der Code zugängig ist, bringt das Verschlüsseln ja auch nicht viel, oder?
Richtig. Deswegen muss bei Programmen wie VeraCrypt der Benutzer immer noch ein Passwort eingeben.
Dieses Passwort dient dann dazu, das Passwort mit dem die Daten verschlüsselt sind, zu ver-/entschlüsseln.

Alles was du im Code oder auf dem Rechner ablegst kann irgendwie ausgelesen werden.
 
jb_alvarado schrieb:
Was ist denn hier die gängige Praxis?
Da nutzt jeder was anderes. CLOUD Sicherung Tools meide ich. Wie man ja wieder gesehen hat aus gutem Grund. Ich nutze Veracrypt. Hier erstelle ich mir dann einen kleinen Container wo ich zu allen Themen meine Wordpad Datei erstelle und dann im Container sichere.

MfG
 
S.Kara schrieb:
Einfach in einer Textdatei ablegen? Oder binär.
Ja Binär wäre noch eine Idee. Muss mich mal schlau machen, ob es dazu fertige Module gibt.

S.Kara schrieb:
Richtig. Deswegen muss bei Programmen wie VeraCrypt der Benutzer immer noch ein Passwort eingeben.
Dieses Passwort dient dann dazu, das Passwort mit dem die Daten verschlüsselt sind, zu ver-/entschlüsseln.

Alles was du im Code oder auf dem Rechner ablegst kann irgendwie ausgelesen werden.
Würde es gerne vermeiden, dass der User noch mal extra sich anmelden muss. Mein Gedanke war: Beim ersten Öffnen der App, kann man in den Settings sein User und API Key eintragen, welche dann verschlüsselt abgelegt werden. In Zukunft öffnet man dann nur noch das App und kann es gleich bedienen.

Wenn man die zugehörige Webseite öffnet, würde der User auch auf Wunsch angemeldet bleiben.

Kann man vielleicht den Secret in einer .env für das Entwickeln speichern, und während dem komilieren wird der Key in das App kompiliert? Rust bietet zumindest die Möglichkeit: https://doc.rust-lang.org/std/macro.option_env.html
 
Zuletzt bearbeitet:
mein Text ist in Yuuri's enthalten und dort ausführlicher
 
Zuletzt bearbeitet:
Entweder sicher oder komfortabel. Komfort und Sicherheit stehen konträr zueinander und verlaufen nicht parallel. Entweder du speicherst es sicher ab, indem der User ein Master-Passwort (oder eben Username + Passwort) vergibt. Oder du speicherst es unsicher ab und der User muss nichts bei jedem Lauf eingeben.
jb_alvarado schrieb:
Verschlüsseln würde ich das Passwort mit argon2, allerdings braucht es dazu einen secret key.
Lies dich bitte ein, wie man verschlüsselt und begehe nicht den Fehler deine eigene "Verschlüsselung" zu bauen, die so oder so in sich zusammen bricht. argon2 verschlüsselt nicht, sondern hasht. Mit argon2 erstellst du einen abgeleiteten Key (siehe auch PBKDF2), der zum Verschlüsseln verwendet werden kann. Und denk nicht dran argon2 mit ner Laufzeit kleiner einer Sekunde zu verwenden, denn dann ist es unsicherer als das Übliche bcrypt. Und verabschiede dich ganz fix von SHA* und Konsorten, von MD* ganz zu schweigen. Nicht umsonst gibt es bei PBKDF in Kombination mit den üblichen Hash-Algorithmen 100.000+ (eher 500.000+) Runden zu absolvieren.
jb_alvarado schrieb:
Jetzt frage ich mich gerade wie man diesen secret key sicher aufbewahrt.
Gar nicht. Wenn du das speicherst, ist die ganze Verschlüsselung sinnlos. Das Pendant zum amerikanischen "den Schlüssel unter die Matte legen".
jb_alvarado schrieb:
Wenn ich ihn im Source Code habe und der Code zugängig ist, bringt das Verschlüsseln ja auch nicht viel, oder?
Ja. Und wenn du den Schlüssel mal änderst, sind gleich mal alle Zugänge deiner Clients ebenso unbrauchbar.
jb_alvarado schrieb:
Ja Binär wäre noch eine Idee.
Und das kann keiner Decoden? Ein anderes Encoding bringt dir genau nichts. Mozilla hat es auch geschafft die komplette Funktion von Windows 10 des Standard-Anwendung-setzen-Prozesses herzuleiten.
jb_alvarado schrieb:
Kann man vielleicht den Secret in einer .env für das Entwickeln speichern, und während dem komilieren wird der Key in das App kompiliert?
Und wo ist der Unterschied zum hardcoded Key im Code? Du kompilierst es genauso in die Anwendung rein.
jb_alvarado schrieb:
Wenn man die zugehörige Webseite öffnet, würde der User auch auf Wunsch angemeldet bleiben.
Wenn du sowieso mit nem Server interagierst, lass den User sich einloggen und erstell danach einen API Key, worüber einzig und allein kommuniziert wird. Username + Passwort müssen so nirgendwo gespeichert werden, sondern einzig der Session Token wird hinterlegt, welcher bei jedem Login oder nach Intervall notfalls rotiert werden kann, ggf. zurückgezogen oder oder oder. Ein Session Token ist aber auch nur ein Kompromiss und weit entfernt von "sicher". Bau also einen üblichen Browser mit Session-Funktionalität nach. Und bitte fang nicht mit JWT an.

PS: die App von die Anwendung (Kurzform von Application) und nicht das Anwendung Programm.
 
  • Gefällt mir
Reaktionen: Madman1209 und ZuseZ3
Yuuri schrieb:
Entweder sicher oder komfortabel. Komfort und Sicherheit stehen konträr zueinander und verlaufen nicht parallel. Entweder du speicherst es sicher ab, indem der User ein Master-Passwort (oder eben Username + Passwort) vergibt. Oder du speicherst es unsicher ab und der User muss nichts bei jedem Lauf eingeben.
@Yuuri, danke für deine Mühe! Ich denke schon, dass man je nach Anwendungsfall auch zwischen sicher und komfortabel abwägen kann und danach dann entwickelt. Es geht hier nicht um super sensible Daten. Kimai ist einfache eine Zeiterfassung mit Projekt-Funktion. Projekte brauche ich noch nicht mal (auch keine Kunden), sondern nur Arbeitszeiten.

Yuuri schrieb:
Lies dich bitte ein, wie man verschlüsselt und begehe nicht den Fehler deine eigene "Verschlüsselung" zu bauen, die so oder so in sich zusammen bricht. argon2 verschlüsselt nicht, sondern hasht. Mit argon2 erstellst du einen abgeleiteten Key (siehe auch PBKDF2), der zum Verschlüsseln verwendet werden kann. Und denk nicht dran argon2 mit ner Laufzeit kleiner einer Sekunde zu verwenden, denn dann ist es unsicherer als das Übliche bcrypt. Und verabschiede dich ganz fix von SHA* und Konsorten, von MD* ganz zu schweigen. Nicht umsonst gibt es bei PBKDF in Kombination mit den üblichen Hash-Algorithmen 100.000+ (eher 500.000+) Runden zu absolvieren.
Wenn du mir dazu ein Rust Modul empfehlen kannst, nehme ich das sehr gerne. Habe selbst Keines gefunden.
Yuuri schrieb:
Gar nicht. Wenn du das speicherst, ist die ganze Verschlüsselung sinnlos. Das Pendant zum amerikanischen "den Schlüssel unter die Matte legen".
Was macht dann z.B. KeyPass mit dem Anmeldepasswort? Wie wird das entschlüsselt und verglichen?

Yuuri schrieb:
Ja. Und wenn du den Schlüssel mal änderst, sind gleich mal alle Zugänge deiner Clients ebenso unbrauchbar.
Wäre kein Problem, dann kann der Client einfach wieder neu sein API Key eingeben.
Yuuri schrieb:
Und das kann keiner Decoden? Ein anderes Encoding bringt dir genau nichts. Mozilla hat es auch geschafft die komplette Funktion von Windows 10 des Standard-Anwendung-setzen-Prozesses herzuleiten.
Hier geht es nicht ums verschlüsseln, sondern Daten strukturiert zu speichern und lesen zu können. Da ist mir solch ein Format lieber, als eine Toml/JSON/YAML etc.
Yuuri schrieb:
Und wo ist der Unterschied zum hardcoded Key im Code? Du kompilierst es genauso in die Anwendung rein.
Der Unterschied ist, dass der Code einsehr bar sein kann, ohne den Schlüssel preis zu geben.
Yuuri schrieb:
Wenn du sowieso mit nem Server interagierst, lass den User sich einloggen und erstell danach einen API Key, worüber einzig und allein kommuniziert wird. Username + Passwort müssen so nirgendwo gespeichert werden, sondern einzig der Session Token wird hinterlegt, welcher bei jedem Login oder nach Intervall notfalls rotiert werden kann, ggf. zurückgezogen oder oder oder. Ein Session Token ist aber auch nur ein Kompromiss und weit entfernt von "sicher". Bau also einen üblichen Browser mit Session-Funktionalität nach. Und bitte fang nicht mit JWT an.
Das ist, soviel ich weiß, von kimai nicht vorgesehen.
 
jb_alvarado schrieb:
Ich denke schon, dass man je nach Anwendungsfall auch zwischen sicher und komfortabel abwägen kann und danach dann entwickelt.
Ich hab das relevante Wort mal hervorgehoben. Von abwägen hast du bisher kein Wort gesagt, sondern einzig von "sicher". Und "sicher" kann man nicht. Daran zerbrechen sich seit Jahrzehnten Menschen den Kopf und keiner bekommt es hin (weil es prinzipiell nicht geht). Bspw. Passwortmanager sind auch nur ein Kompromiss. Nicht umsonst gibt es jetzt den drölfzigsten Ansatz mit Passkeys um Passwörter "obsolet" machen zu wollen. Passkeys haben aber andere Schwächen, deutlich eklatantere als Passwortmanager imho.
jb_alvarado schrieb:
Wenn du mir dazu ein Rust Modul empfehlen kannst, nehme ich das sehr gerne.
Keine Ahnung, kenne mich in Rust viel zu wenig aus. Aber du brauchst kein "Modul" dafür (abseits von der Verschlüsselung und dem Hashen), du musst den Prozess korrekt abbilden und die Daten korrekt vorbereiten. Wie du eine Schleife baust. Dafür gibts kein Modul, das ist der übliche Prozess. "Einfache Kryptographie" existiert nicht. Und wenn ist sie immer anfällig.
jb_alvarado schrieb:
Was macht dann z.B. KeyPass mit dem Anmeldepasswort? Wie wird das entschlüsselt und verglichen?
KeePass fragt bei jedem Start das Master-Passwort ab. Das wird nirgendwo hinterlegt, das musst du bei jedem Aufruf neu eingeben. Du kannst dich hier auch weiterhin ans OS heften und davon bereitgestellten APIs und Credential Manager verwenden. Das ist aber auch Aufwand den du treiben musst, ggf. crossplatform.

KeePass nutzt zusätzlich die vom OS bereitgestellte DPAPI um u.a. das Master-Passwort im RAM zu halten. Hier wird vom System die Sicherheit bereitgestellt und nicht durch dich. Aber auch diese kann man prinzipiell umgehen (siehe DataProtectionDecryptor)...
jb_alvarado schrieb:
Wäre kein Problem, dann kann der Client einfach wieder neu sein API Key eingeben.
Hm nein... Nur weil du mit jedem Release deinen öffentlichen Encryption Key änderst (den man problemlos aus der Binary auslesen kann *hust*), will der User deswegen nicht permanent seine Zugangsdaten neu eingeben. Ein API Key ist auch nur mehr ein Shared Key, den mindestens beide Gegenstellen kennen.
jb_alvarado schrieb:
Der Unterschied ist, dass der Code einsehr bar sein kann, ohne den Schlüssel preis zu geben.
Dein Schlüssel wird mit jedem Kompilat direkt in der Datei weitergegeben. Du kannst den Schlüssel nicht "nicht preisgeben", um ihn dann irgendwo doch zu verwenden.

Security through Obscurity ist immer dumm und fällt dir immer auf die Füße. -> Schlüssel unter der Fußmatte

Und genau das machst du hiermit. Siehe auch Tools wie WebBrowserPassView und Mail PassView.
jb_alvarado schrieb:
Das ist, soviel ich weiß, von kimai nicht vorgesehen.
Dann nutz auch die Funktion der API Keys. Diese Shared Keys sind vom Prinzip her nicht sicher, weil mindestens zwei Geräte diese kennen und auch prinzipiell jeder kennt, der den Traffic mitschneidet (außer du verwendest TLS zur Transportverschlüsselung, außer du verwendest auch nen "Virenscanner", welcher TLS aufbricht oder dann den Key zur "Überwachung" im Dateisystem durchleuchtet). Spätestens dann ist es aber auf deinem Gerät wieder unverschlüsselt. API Keys muss man auch nicht verschlüsseln, denn diese kann man bei einer ggf. Kompromittierung einfach rotieren (was bei Passwörtern schlechter geht).

Du kannst prinzipiell jeden API Key aus deinem Browser auslesen, wenn dir danach ist. Diese liegen auch unverschlüsselt vor, entweder Cookie oder im Local Storage direkt im Dateisystem.

FileZilla und Konsorten speichern ihre Zugänge auch ab. Aber nur in einem anderen Encoding, das man problemlos dekodieren kann. Ohne Master-Passwort ist auch hier nichts sicher. Einige speichern Zugangsdaten auch gern als Base64. Genauso sinnfrei - dem User täuscht man Sicherheit vor, dem Script-Kiddy ist das komplett egal.

Bestenfalls stellt man dich als inkompetent dar und überlegt sich zukünftig, ob man dir nochmal glaubt. Bei den heutigen Leaks ist das mit der Glaubwürdigkeit und dem Vertrauen allerdings etwas weit gehofft...

TL;DR:
  • Sicher ist einzig ein Master-Passwort, was nur der User kennt. Das liegt zur Runtime aber temporär plain im RAM, aber persistiert wird es nirgendwo.
  • Lass die "Verschlüsselung" sein und leg es so ab, weise den User ggf. darauf hin.
  • Oder nutz Shared Keys (nicht sicherer als unverschlüsselt, aber einfacher rotierbar).
Im Falle von kimai, was eh schon API Keys verwendet, wäre letzteres die entsprechende Wahl.

Aber implementiere keine "Verschlüsselung" (auch nicht on top), die man beim nächsten Augenzwickern einfach brechen kann und lass den User nicht im Glauben, dass irgendwas "sicher" wäre.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Yuuri schrieb:
Aber implementiere keine "Verschlüsselung" (auch nicht on top), die man beim nächsten Augenzwickern einfach brechen kann und lass den User nicht im Glauben, dass irgendwas "sicher" wäre.
Habe ich so noch nicht gesehen und muss ich mich erst mal dran gewöhnen :-).
 
Zurück
Oben