# Passwort verschlüsseln und wieder entschlüsseln



## beta20 (2. Apr 2019)

Hallo,

ich habe folgendes Szenario:
a) User gibt Emailkonfiguration von seinem Provider ein um Emails von meinem Webinterface abzurufen
b) Passwort soll verschlüsselt in der Datenbank abgespeichert werden
c) Beim Abrufen der Emails, muss das Passwort dann natürlich wieder entschlüsselt werden

Nun meine Frage:
- Was kann ich hier verwenden?
- Wie macht man das am Besten?

Meines Wissens benötige ich ja einen privaten / public Key?
Stand jetzt habe ich einen privaten Key als String und AES. Ist das aber richtig?
Wäre es besser ein binäres File zu erstellen, was meinen privaten Key hat?

Wäre so etwas brauchbar?





						Key-File im selben Ordner speichern?
					

Hallo ihr lieben Java-Coder,  habe eine allgemeine Frage zum Thema Verschlüsselung.  Ich habe ein Programm geschrieben worin man Kundendaten eingeben und als Datei abspeichern kann. Diese werden mit einem AES-Key, den ich ebenfalls als File abspeichere, verschlüsselt. Kann ein fremder die...



					www.java-forum.org
				




oder:








						AES.java - Pastebin.com
					

Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.




					pastebin.com
				




Wie erzeuge ich solch ein File?

Für Tipps, Ratschläge bin ich sehr dankbar.


----------



## Robat (2. Apr 2019)

beta20 hat gesagt.:


> c) Beim Abrufen der Emails, muss das Passwort dann natürlich wieder entschlüsselt werden


Warum? Verschlüssel doch einfach das eingegebene Passwort und schau ob am Ende der selbe Hash rauskommt.


----------



## mihe7 (2. Apr 2019)

Robat hat gesagt.:


> Warum?


Vermutlich wird das Passwort benötigt, um sich beim Mail-Server zu authentifizieren.


----------



## beta20 (2. Apr 2019)

Robat hat gesagt.:


> Warum? Verschlüssel doch einfach das eingegebene Passwort und schau ob am Ende der selbe Hash rauskommt.


Wie meinst du das? Verstehe ich nicht.
Für die Anmeldung beim Emailprovider brauche ich doch wieder das richtige Passwort und nicht das verschlüsselte???


----------



## Robat (2. Apr 2019)

Natürlich... Ist noch zu früh


----------



## mrBrown (2. Apr 2019)

Muss der Nutzer sich in deiner Web-App einloggen, bevor die Mails abgerufen werden?


----------



## mihe7 (2. Apr 2019)

beta20 hat gesagt.:


> Meines Wissens benötige ich ja einen privaten / public Key?


Das wäre asymmetrische Verschlüsselung. AES ist symmetrisch. 

Um das sicher zu machen, dürftest Du den Schlüssel, mit dem Du das Passwort entschlüsselst, nicht auf dem System speichern. Dazu erzeugt man den Schlüssel normalerweise aus dem Benutzerpasswort.


----------



## beta20 (2. Apr 2019)

Ja, der User muss ich zuvor in der WebApp anmelden, bevor er Mails abrufen kann.




mihe7 hat gesagt.:


> Das wäre asymmetrische Verschlüsselung. AES ist symmetrisch.
> 
> Um das sicher zu machen, dürftest Du den Schlüssel, mit dem Du das Passwort entschlüsselst, nicht auf dem System speichern. Dazu erzeugt man den Schlüssel normalerweise aus dem Benutzerpasswort.


1) Wo speichere ich dann den Schlüssel ab? Ich habe doch nur zwei Möglichkeiten a) Datenbank b) FileDrive ?

2) Benutzerpasswort ist eher schlecht, denn:
    -> Meine App hat 1....n Firmen (auch Mandanten genannt)
    -> 1 Mandant ..... n Employee
    -> 1 Mandant ... n Emailpostfächer
    -> Jeder Employee sollte auch Zugriff auf das Emailpostfach haben können (mind. Emails versenden). 
    -> Jeder Employee hat sein eigenes Passwort


----------



## mihe7 (2. Apr 2019)

1) Gar nicht.
2) Benutzerpasswort ist != E-Mail-Passwort - das funktioniert natürlich nur, wenn sich der Benutzer an Deiner Web-Anwendung anmeldet.

EDIT: gerade gesehen, dass Du oben bereits geschrieben hast, dass sich der Benutzer anmeldet. Dieses Passwort wäre dann das Benutzerpasswort, aus diesem generierst Du einen Schlüssel, den Du für die Ver-/Entschlüsselung der Login-Daten des E-Mail-Accounts verwendest. Siehe z. B. https://de.wikipedia.org/wiki/PBKDF2 sowie https://www.baeldung.com/java-password-hashing


----------



## mrBrown (2. Apr 2019)

beta20 hat gesagt.:


> 1) Wo speichere ich dann den Schlüssel ab? Ich habe doch nur zwei Möglichkeiten a) Datenbank b) FileDrive ?


Den speicherst du gar nicht ab, sodern generierst ihn bei jedem Login neu aus dem Passwort.



beta20 hat gesagt.:


> Benutzerpasswort ist eher schlecht, denn:
> -> Meine App hat 1....n Firmen (auch Mandanten genannt)
> -> 1 Mandant ..... n Employee
> -> 1 Mandant ... n Emailpostfächer
> ...


Sag doch gleich, dass du so einen Spezialfall abdecken musst 

Ich weiß ehrlich gesagt nicht, ob es dafür eine Patentlösung gibt...
Eine Möglichkeit ist aber, die von @mihe7 um eine Ebene zu erweitern, in dem man einen Schlüssel (per User) für den eigentlichen Schlüssel einführt, keine Ahnung ob das in diesem Fall das sinnvollste ist...


----------



## beta20 (2. Apr 2019)

ich fasse es mal zusammen:
1) Schlüssel speichere ich nirgends
-> privater Schlüssel ist dann der HASH vom originalen Passwort der Benutzeranmeldung?
-> Ich verwende derzeit hierfür SHA512

2) Verschlüsseltes Email Passwort speichere ich in der Datenbank
3) Entschlüsselung des Email Passworts geschieht dann über den privaten Schlüssel (HASH von Benutzeranmeldung)

4) Ändert der User sein Passwort, muss ebenfalls das Emailpasswort in der DB geändert werden (da sich dann der private Schlüssel ändert)

_____________

Gemeinsamer Zugriff:
- Um den gemeinsamen Zugriff ermöglichen:
  -> Eine neue Tabelle einführen, die so aussieht:
     a) User b) Schlüssel
  -> Durch den Schlüssel je User, bekomme ich dann den eigentlichen Schlüssel für die Email?

Könnte das so aussehen? Bei dem gemeinsamen Zugriff sind mir die Erstellung der utnerschiedlichen Schlüssel noch nicht ganz klar. Insbesondere der Zugriff auf den "globalen Schlüssel"


----------



## Thallius (2. Apr 2019)

Da du den Hash des Passwortes ja sicher in deiner DB speicherst um beim Login zu schaun ob der User das richtige Passwort eingegeben hat, wäre es nicht schlau diesen eh in der DB stehenden Hash zu nehmen um das Email-Passwrot zu verschlüsseln. Hier solltest du das richtige Passwort nehmen und nicht dessen Hash. Damit must du zwar das PW übers Netz schicken (Was auch nicht so schön ist) aber solange Du nur mit TLS arbeitest sollte das nicht so schlimm sein.

Gruß

Claus


----------



## mrBrown (2. Apr 2019)

beta20 hat gesagt.:


> 1) Schlüssel speichere ich nirgends
> -> privater Schlüssel ist dann der HASH vom originalen Passwort der Benutzeranmeldung?
> -> Ich verwende derzeit hierfür SHA512


DU darfst *nicht* den Hash als Schlüssel nutzen, den du schon in der DB gespeichert hast. Für das Passwort nimmt man im Idealfall eine extra für Passwörter entwickelte Hash-Funktion, für den Schlüssel dann etwas anderes.




Thallius hat gesagt.:


> Damit must du zwar das PW übers Netz schicken (Was auch nicht so schön ist) aber solange Du nur mit TLS arbeitest sollte das nicht so schlimm sein.


Wo, außer dem initialen Login, wird das Passwort dabei übers Netz geschickt?


----------



## Thallius (2. Apr 2019)

mrBrown hat gesagt.:


> Wo, außer dem initialen Login, wird das Passwort dabei übers Netz geschickt?



Habe ich das behauptet? Aber für den intialen Login muss man das Passwort ja auch nicht zwangsweise übers Netz schicken. Das geht auch eleganter indem man sich vom Server einen Schlüssel zum Hashen holt und dann nur den Hash verschickt.

Gruß

Claus


----------



## mrBrown (2. Apr 2019)

beta20 hat gesagt.:


> Gemeinsamer Zugriff:
> - Um den gemeinsamen Zugriff ermöglichen:
> -> Eine neue Tabelle einführen, die so aussieht:
> a) User b) Schlüssel
> ...


Für das Mail-Passwort wird ein zufälliger Schlüssel generiert, das Mail-Passwort wird dann mit diesem verschlüsselt gespeichert.
Der Schlüssel wird für jeden Nutzer mit dessen Passwort (bzw, daraus abgeleiteten Schlüssel) verschlüsselt und pro Nutzer gespeichert.

Beim entschlüsseln wird mit dem Nutzer-Passwort der Schlüssel entschlüsselt, und mit diesem dann das Mail-Passwort.


----------



## mihe7 (2. Apr 2019)

Im zweiten Link ist ein Beispiel für PBKDF unter Java angegeben. Es ist hier nicht einfach nur ein Hash, sondern ein spezieller Hash des Benutzerpassworts. Am besten wäre es, wenn die Hashfunktion für den Schlüssel eine andere ist als die, mit der Du den Hash für die Benutzer-DB erzeugst (sonst hast Du einen Angriffspunkt für den Schlüssel in der DB stehen).

Hintergrund ist, dass Passwörter in der Regel nicht genau die erforderliche Bitlänge des Schlüssels haben und oft nicht über ausreichende Entropie verfügen. Daher wird das Passwort mit einer Hash-Funktion auf den Schlüssel abgebildet. Ein einfacher Hash ist sehr schnell berechnet, weshalb Angriffe über das Passwort durchaus möglich wären. Aus diesem Grund setzt man hier ein Verfahren ein, das "möglichst" lange dauert. Wenn Du für vier Versuche 1 Sekunde benötigst, vergeht Dir schnell die Lust am Durchprobieren, weil Du in den nächsten Jahren keinen Erfolg haben wirst.


----------



## mihe7 (2. Apr 2019)

Thallius hat gesagt.:


> Das geht auch eleganter indem man sich vom Server einen Schlüssel zum Hashen holt und dann nur den Hash verschickt.


Dann kannst Du die Passwörter auch im Klartext speichern.

Nachtrag: Um das für Mitleser nochmal klar gesagt zu haben: macht das nicht.


----------



## beta20 (2. Apr 2019)

OK, heißt das dann.

*MailPasswort:*
- Zufälliger Schlüssel generiert (createRandomKey)
- Mail-Passwort wird verschlüsselt mit dem "Zufälligen Schlüssel" generiert und in der DB gespeichert

*Schlüssel Nutzer:*
- "Zufälliger Schlüssel" wird mit dem Benutzerpasswort verschlüsselt. Der verschlüsselte Schlüssel wird dann in der DB gespeichert
-> Extra Tabelle (ID, Passwort, Employee_FK, EmailSetting_FK)

______________________________________________

Folgende Fälle müssen beachtet werden:

*a) Benutzer ändert sein Passwort. *
   -> Dann muss in der Datenbank das verschlüsselte Passwort (Schlüssel Nutzer) ebenfalls geupdatet werden

*b) Neuer Benutzer wird erstellt*
   -> Dieser hat ja zunächst kein Tabelleneintrag auf das Emailpostfach. Hierzu muss dann für jedes Mailpostfach ein Tabelleneintrag erstellt werden (Schlüssel Nutzer)

-> Bitte um Prüfung, ob das so passt...


----------



## mihe7 (2. Apr 2019)

beta20 hat gesagt.:


> Dann muss in der Datenbank das verschlüsselte Passwort (Schlüssel Nutzer) ebenfalls geupdatet werden


Richtig.


beta20 hat gesagt.:


> Hierzu muss dann für jedes Mailpostfach ein Tabelleneintrag erstellt werden (Schlüssel Nutzer)


Richtig. EDIT: beim Hinzufügen der Mailbox müssen die von Dir unter "MailboxPasswort" und "Schlüssel Nutzer" genannten Schritte ausgeführt werden. Das muss nicht unbedingt etwas mit dem "neuen" Benutzer zu tun haben.


----------



## mrBrown (2. Apr 2019)

beta20 hat gesagt.:


> *a) Benutzer ändert sein Passwort. *
> -> Dann muss in der Datenbank das verschlüsselte Passwort (Schlüssel Nutzer) ebenfalls geupdatet werden


Ja, bei der Änderung hast du ja immer altes und neues Passwort, also gespeicherten, verschlüsselten Schlüssel mit altem Entschlüsseln und mit neuem verschlüsselt speichern.



beta20 hat gesagt.:


> *b) Neuer Benutzer wird erstellt*
> -> Dieser hat ja zunächst kein Tabelleneintrag auf das Emailpostfach. Hierzu muss dann für jedes Mailpostfach ein Tabelleneintrag erstellt werden (Schlüssel Nutzer)


Ja. 
Für das erstellen des Tabelleneintrags brauchst du aber den entschlüsselten, "zufälligen Schlüssel", daher muss dabei immer ein weitere Nutzer beteiligt sein, der Zugriff darauf hat.


----------



## Thallius (2. Apr 2019)

mihe7 hat gesagt.:


> Dann kannst Du die Passwörter auch im Klartext speichern.
> 
> Nachtrag: Um das für Mitleser nochmal klar gesagt zu haben: macht das nicht.



Hae? Dann ist jede Art der zwei Faktor Authentifizierung schlecht in deinen Augen. Ich glaube du hast da was nicht richtig verstanden....


----------



## mrBrown (2. Apr 2019)

Thallius hat gesagt.:


> Hae? Dann ist jede Art der zwei Faktor Authentifizierung schlecht in deinen Augen. Ich glaube du hast da was nicht richtig verstanden....


Hae? Was soll zwei Faktor Authentifizierung mit Client-Side-Hashing zu tun haben? Ich glaube du hast da was nicht richtig verstanden....


----------



## Thallius (2. Apr 2019)

mrBrown hat gesagt.:


> Hae? Was soll zwei Faktor Authentifizierung mit Client-Side-Hashing zu tun haben? Ich glaube du hast da was nicht richtig verstanden....


Ist doch das gleiche Prinzip. Ob ich nun einen Token abhole und den benutze oder einen Salt den ich zum hashen benutze ist doch nur eine Frage der Begrifflichkeit


----------



## mrBrown (2. Apr 2019)

Thallius hat gesagt.:


> Ist doch das gleiche Prinzip. Ob ich nun einen Token abhole und den benutze oder einen Salt den ich zum hashen benutze ist doch nur eine Frage der Begrifflichkeit


Wie 2FA umgesetz ist, ist reines Implementierungsdetail, es muss also nicht mal einen Token der abgeholt wird geben.
Ein einmaliger Token ist keineswegs mit einem Salt zum Hashen vergleichbar...


Einfach https nutzen, dann ist das Passwort immer verschlüsselt und man muss es nicht selbst noch irgendwie umsetzen und dabei uU das ganze schwächer machen...


----------



## mihe7 (2. Apr 2019)

@Thallius vielleicht habe ich Dich tatsächlich falsch verstanden. Gegenfrage: wenn Du den Hash zu Anwendung geschickt hast, was macht die damit? Womit wird der Hash verglichen?


----------



## Xyz1 (2. Apr 2019)

@beta20 Also gängig ist, das Passwort im Klartext zu speichern. Zum zusätzlichen Schutz kann der Benutzer ein Passwort eingeben, um das Passwort zu speichern.


----------



## mrBrown (2. Apr 2019)

Tobias-nrw hat gesagt.:


> @beta20 Also gängig ist, das Passwort im Klartext zu speichern. Zum zusätzlichen Schutz kann der Benutzer ein Passwort eingeben, um das Passwort zu speichern.


WTF


----------



## petebocs (2. Apr 2019)

Standard Lösung eventuell?
Oauth


----------



## mrBrown (2. Apr 2019)

petebocs hat gesagt.:


> Standard Lösung eventuell?
> Oauth


Wen siehst du denn da in welchen Rollen?


----------



## petebocs (3. Apr 2019)

Ich dachte es ist eindeutig: "Ein Endbenutzer (_User_ oder _Resource Owner_) kann mit Hilfe dieses Protokolls einer Anwendung (_Client_ oder _Third-Party_) den Zugriff auf seine Daten erlauben (_Autorisierung_), die von einem anderen Dienst (_Resource Server_) bereitgestellt werden, ohne geheime Details seiner Zugangsberechtigung(_Authentifizierung_) dem Client preiszugeben." 

Zum Beispiel Gmail unterstützt Oauth:








						Authorizing Your App with Gmail  |  Google Developers
					






					developers.google.com


----------



## Xyz1 (3. Apr 2019)

Nach den Stakeholdern habe ich mich auch schon gefragt... Imho ist ein "Endbenutzer" hier gleichzusetzen mit einem "Client". Damit bringts wohl nix.


----------



## mihe7 (3. Apr 2019)

Ich sehe hier ein ganz andere Problem:


petebocs hat gesagt.:


> Zum Beispiel Gmail unterstützt Oauth:


Das ist schön aber hier geht es, wenn ich mich nicht täusche, um den Abruf von Mails. Das dürfte via IMAP/POP erfolgen und soweit ich das sehe müsste dazu der Anbieter XOAuth unterstützen. Wer außer Gmail macht das?


----------



## petebocs (4. Apr 2019)

Ok, wie ich es verstanden diese Protokoll könnte hier die Lösung sein. 
Hier gibt es eine Liste mit den Providern:
https://en.wikipedia.org/wiki/List_of_OAuth_providers


----------



## mrBrown (4. Apr 2019)

petebocs hat gesagt.:


> Ich dachte es ist eindeutig: "..."


Wikipedia kann ich auch lesen...

Mir war bisher kein Multi-User, OAuth-fähiger Mail-Provider bekannt, deshalb die Frage ^^



petebocs hat gesagt.:


> Ok, wie ich es verstanden diese Protokoll könnte hier die Lösung sein.
> Hier gibt es eine Liste mit den Providern:
> https://en.wikipedia.org/wiki/List_of_OAuth_providers


Interessanter wären Mail-Provider mit XOAuth(2)...Microsoft unterstützt das sieht auch, aber sonst?


----------



## mihe7 (4. Apr 2019)

Wir können das, wie mir scheint, abkürzen: XOAuth ist nicht weit verbreitet -> kein Standard -> keine Lösung.


----------



## petebocs (4. Apr 2019)

OK, dann kein Standard, keine Lösung.


----------



## mihe7 (4. Apr 2019)

Leider. De Idee wäre ja goldrichtig: gar keine Anmeldedaten auf dem eigenen Server


----------

