Daten sicher speichern

ich weis das man daten eigentlich nie lokal speichern sollte, also zumindest nicht solche die irgendeine sicherheitsbewandnis haben wie zugangsdaten und sowas
in meinem fall komme ich aber nicht drum rum da ich einen e-mail-client schreiben möchte, und dazu ja irgendwie abrufbereit die login-daten speichern muss
wie machen sowas zum beispiel outlook, thunderbird und andere ?

weil mir ist schon klar : hashen geht nicht da ich die daten im klartext brauche, verschlüsseln fällt auch flach da durch den code gefiltert wieder lesbar oder spätestens im RAM abgreifbar
es geht mir hier nicht irgendwie “um den lerneffekt” oder “wie funktioniert das”, sondern ich möchte mir halt einen auf meine bedürfnisse angepassten e-mail-client selbst schreiben und stolpere dabei halt über diese frage

für konzept ideen bin ich gerne offen, vielleicht hat ja der eine oder andere noch ne idee wie man sowas “gut” umsetzen könnte

[quote=Ziv]verschlüsseln fällt auch flach da durch den code gefiltert wieder lesbar oder spätestens im RAM abgreifbar[/quote]Wenn das Dein Kriterium ist dann gibt es keine Lösung. Bei jedem Verfahren liegt das Passwort früher oder später im Klartext im Ram des Rechners. (Wie anderst sollte man es sonst auch verwenden können?)

Darüber hinaus liefern die Suchworte “java crypto api” einige gute Treffer in Metager

bye
TT

Browser und Mailprogramme verwenden normalerweise einen Passwortsafe. Das bedeutet, dass der Nutzer der Anwendung ein Masterpasswort einmal eingeben muss. Damit werden dann die gespeicherten Passworte entschlüsselt. Alternativ bieten diese Programme auch einen “Passwortsafe” ohne Masterpasswort an, sodass gar kein Passwort eingegeben werden muss. Dadurch sind die Passworte nicht geschützt.
Die maximale Sicherheit erhältst du, wenn du die Passworte nur so kurz wie möglich unverschlüsselt im Speicher lässt. D. h., dass bei jedem Versenden / Abrufen der Mails das Masterpasswort eingegeben werden muss. Da du das wohl nicht möchtest, bleibt dir nur der Weg, das Auslesen etwas zu erschweren.
Ich würde dabei folgendes Vorgehen vorschlagen:
[ul][li]der Nutzer meldet sich mit dem Masterpasswort beim Mailprogramm an[/li][li]das Programm generiert einen zufälligen Schlüssel[/li][li]das Programm entschlüsselt den Passwortsafe und verschlüsselt ihn mit dem zufällig generierten Schlüssel[/li][li]bei Bedarf (also sobald die Mails abgerufen werden) wird das neu verschlüsselte Passwort mit dem zufällig generierten Schlüssel entschlüsselt, nach Verwendung muss der Speicher überschrieben werden[/li][/ul]

@TT
das mit “keine lösung” würde ich so vielleicht nicht ganz blind unterschreiben
klar, irgendwann muss bei einem verfahren das nunmal das kennwort an einer gewissen stelle im klartext erfordert dies dann auch verfügbar sein
aber dennoch sollte es ja wohl möglich sein es nicht “ganz so offensichtlich” zu speichern

@cmr
ja, passwortsafe ist sicher auch eine möglichkeit, und viele programme bieten entsprechende funktionen an, diese sind aber meist standardmäßig nicht aktiv da für die breite einfach nicht “bequem genug”

es geht mir auch eher weniger um meinen code als mehr um die frage wie sowas bei produktiver software gelöst wird
vor allem entsprechend der user-freundlichkeit, oder besser : der bequemlichkeit auf kosten der sicherheit entsprechend

ist halt doch scheinbar ein etwas komplexeres thema als ich dachte

Und ebendiese Bequemlichkeit geht zu Lasten der Sicherheit. Wenn es kein Masterpasswort gibt, kann man die Passworte problemlos auslesen. Die meisten Programme bieten ja sogar eine Möglichkeit, um die Passworte direkt im Klartext anzeigen zu lassen…

gut, aber selbst wenn wir mal von ausgehen das ich sowas wie einen master-passwort-gesicherten “safe” einbaue, wie weit würde man dann hier mit java kommen ?
ich rede dabei nicht von “spezial-libs” wie BouncyCastle sondern von der ganz normalen JCE die oracle mitliefert … ach wo wir grad dabei sind : wie siehts in dem punkt eigentlich mit alternativen VMs wie die von apple oder icedtea aus ? nutzen diese eigentlich die “offiziellen” crypto-libs von oracle oder haben diese eigene, vielleicht sogar in-kompatible implementierungen ? und würde es überhaupt sinn machen z.b. bouncy zu nutzen ?

ich würde z.b. folgende implementierung in betracht ziehen

inhalt des “safes” mit AES128 (es soll ja unter jeder VM laufen)
den AES-key mit RSA2048 (braucht zwar etwas mehr zeit als RSA1024, läuft aber immer noch auf jeder VM)
den RSA-private mit PBE der aus dem master-passwort erzeugt wird

theoretisch könnte man den RSA-public dann sogar noch “wegwerfen” nach dem man den AES-key gesichert hat, weil man den key ja nur noch lesen muss

oder würdet ihr hier ganz auf sicherung mit AES und RSA verzichten und direkt mit PBE arbeiten ?
ja, mir ist auch bekannt das man aus einem password-input auch direkt AES oder RSA schlüssel erzeugen kann, und ich weis auch erlich gesagt nicht wie sicher PBE ist, aber dann wollte ich die möglichkeiten die java bietet schon mal ausnutzen

RSA brauchst du nicht, du überträgst ja keine Daten über einen unsicheren Kanal. Du brauchst noch PBKDF2, um einen symmetrischen Schlüssel aus dem Passwort zu generieren. AES128 oder eher AES mit 256 Bit Schlüssel sind für den Passwortsafe empfehlenswert.
Probleme sehe ich beim Überschreiben des Passwortstrings, die normale Stringklasse ist dafür nicht geeignet, weil der Speicher nicht gezielt überschrieben werden kann. In Java habe ich noch nichts hinsichtlich Verschlüsselung gemacht, daher kann ich da auch keine geeignete Klasse empfehlen, die wird es aber sicherlich geben.

*** Edit ***

Ich sehe gerade, dass [japi]PBEKeySpec[/japi] mit char[] arbeitet, da kannst du das Passwort natürlich problemlos überschreiben. Bleibt nur noch die Frage, wie du das Passwort eingeben lässt und die zugehörige Speicherstelle überschreibst.

[quote=Ziv]das mit “keine lösung” würde ich so vielleicht nicht ganz blind unterschreiben[/quote]Die Anforderung war für mich eindeutig definiert: Passwort nicht als Klaartext im RAM und das geht nicht…

[quote=Ziv;80694]aber dennoch sollte es ja wohl möglich sein es nicht “ganz so offensichtlich” zu speichern[/quote]Sicher das geht, da gibts auc tausend und ein Beispiel im Netz…

bye
TT

@cmr
nicht umsonst hatte ich PBE bereits erwähnt
ich hab mich nur in der klasse geirrt : PBEKeySpec wird einer SecretKeyFactory übergeben > symetrisch > AES

AES256 würde nur mit BC in frage kommen da die normale JCE ohne extension nur AES128 erlaubt
und selbst wenn wäre es bei AES256 nur ein doppelt so langer schlüssel, die block-größe bleibt bei 128

Du hast zwei Probleme:
[ol]
[li]Speicherung auf lokaler Festplatte
[/li][li]Anmeldung am Remotesystem
[/li][/ol]
Die Speicherung auf der lokalen Festplatte kannst Du verschlüsseln. Dafür gibt es genügend Beispiele im Forum und/oder Internet.

Das andere Problem, Anmeldung am Remotesystem, kannst Du nicht lösen. Die System die ich da kenne verlangen mehr oder weniger das Klartextpasswort. Mehr oder weniger bedeutet in dem Fall das irgend welche Hash aus dem Klartext berechnet (Klartext muss also lokale gespeichert werden) werden oder das die Passwörtder über SSL etc. verschlüssel (aber halt Klartext, muss lokal gespeichert werden) übertragen werden.

Meine Lösung würde darauf basieren das die lokalen Daten verschlüsselt sind (z.B. Masterpasswort). Und das die Passwörter im eigenen Quellcode sauber zerstört werden nach dem Benutzen. Was externe Librarys an der Stelle machen kannst Du nicht kontrollieren.

hand, mogel

Ich habe ja auch von der Schlüssellänge geredet und nicht von der Blocklänge. Die Schlüssellänge ist maßgeblich für die Qualität der Verschlüsselung.
Prinzipiell betrachte ich das Thema hier auch mehr als grundsätzliche Frage denn als javaspezifisches Problem.

Ansonsten sind dir glaube ich alle Hinweise gegeben worden.

was mir irgendwie noch fehlt ist der punkt : wie machens die großen ?
wie schon erwähnt : sehr viele programme bieten dinge wie “masterpasswort” und der gleichen an, nutzen diese standardmäßig aber nicht > ergo stellt sich die frage : wie werden die daten dann “gesichert” abgelegt ?
in einem solchen fall macht es keinen unterschied ob man das kennwort selbst plain speichern (quasi wie ein offenes tor) oder halt kryptografisch sichert und dann aber “den schlüssel fürs schloss an einen nagel daneben hängt”

und das ganze soll ja auch eigentlich nur für mich sein, und ich selbst hab auch kein problem damit bei jeder verbindung meine anmelde-daten einzugeben (mach ich eh da mein browser auf “beim beenden temp-daten löschen” eingestellt ist)
und ja : es ist auch eher eine grundsätzliche frage als eine java-spezifische (die implementierung sollte für mich kein problem sein)

aber man sollte sich ja normalerweise vor der implementierung gedanken übers konzept machen