SMTP Zugangsdaten im Programm speichern

  • VB.NET

Es gibt 76 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    DerSmurf schrieb:


    Hier hat mich @VaporiZed darauf aufmerksam gemacht, wie kompliziert es ist mehrere DataTable in einem Projekt unterzubringen.


    Mehrer DataSet's meinst Du sicher.

    Kompliziert finde ich es gar nicht, nur ist die Frage ob Sinnvoll. Das kommt halt auf den Einzelfall drauf an. Ich brauche ein DataSet allein für "Voreinstellwerte" und weitere DataSets für den jeden einzelnen Import von speziellen Fremddaten. Diese sind aber für das Programm gesehen nur temporär nötig.

    Gruß
    Rob
    Hoi
    Ja, ich meine DatSet. Sorry!

    Dann ist ja meine Situation, mit deiner Verwendungssituation der DataSets vergleichbar.
    Ich werde heute Abend einfach mal testen.

    Edit zu meinem letzten post.
    Zum Thema DataSet lernen möchte ich natürlich auch die genialen Tuts, sowie die Youtube Reihe vom @ErfinderDesRades nennen.
    Nun, Du kannst mehrere tDSs verwenden, es ist ja möglich. Nur eben komplizierter. Und abhängig davon, ob Du die EdR-Helper benutzt, ggf. nicht ohne weiteres möglich. Aber unmöglich ist es nicht.
    Aber es geht auch m.E. einfacher: Bevor Du den Inhalt des Haupt-tDS speicherst, verschlüssele und speichere den Inhalt der Settings-Table in eine Extra-Datei, lösche den Settings-Table-Inhalt und speichere dann den kompletten (Rest vom) tDS-Inhalt. WriteXML geht ja nicht nur für's tDS, sondern auch für ne DataTable. Und wenn Du dann lädst, lädst Du erst den tDS-Content und dann - tja. Dann musst Du selber entscheiden, welche Datei Du für die Settings-Table hernimmst. Du könntest zu Programmstart z.B. ne User-Auswahl ermöglichen, dann muss nach Auswahl des Users dessen Master-Passwort eingeben und dann wird dessen Settings-XML-Datei geladen. Oder zumindest versucht. Denn wenn das Passwort falsch ist, ergibt das Entschlüsseln (codeabhängig) nen Leerstring oder ne Exception. Und dann weißt Du, dass das Passwort falsch war und das Programm beendet sich oder der User darf das PW nochmal eingeben oder die SSD des PCs wird aus Boshaftigkeit formatiert (ok, letzteres ist vielleicht etwas Overkill :D )

    btw:

    DerSmurf schrieb:

    Hier hat mich @VaporiZed darauf aufmerksam gemacht, wie kompliziert es ist mehrere DataTable in einem Projekt unterzubringen.
    mehrere DataSets, nicht DataTables.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Erst mal vorweg, ich will nicht den Rahmen des Threads sprengen, aber (war klar) ich meine doch etwas klar stellen zu müssen.

    VaporiZed schrieb:

    Und abhängig davon, ob Du die EdR-Helper benutzt, ggf. nicht ohne weiteres möglich.

    Waaaaaas? Warum das nicht, was soll daran jetzt schwierig sein? Ich benötige mehrere Datasets, und das ist nicht wirklich schwer das zu händeln. Ob es Sinnvoll ist, ist eine ganz andere Frage.

    VaporiZed schrieb:

    ... speichere den Inhalt der Settings-Table in eine Extra-Datei..

    Was machst Du wenn Du generelle Einstellungen ändern musst aber die aktuellen Einstellungen des Benutzers nicht ändern darfst ohne dass dieser Zustimmt? Klar ist ein manueller Abgleich nötig, aber bei mir wäre das nur schwer anders zu lösen, ausser ich würde für alle Anwender eine zentrale DB verwenden. Auch hier kommt es doch sehr darauf an, worum es im Einzelnen tatsächlich geht.[/quote]

    VaporiZed schrieb:

    mehrere DataSets, nicht DataTables.

    Jo, das hatten wir aber schon geklärt.

    Dksksm schrieb:

    Warum das nicht, was soll daran jetzt schwierig sein?
    Ich habe keine Ahnung von den Möglichkeiten der EdR-Helpers, da ich sie nicht nutze.

    Dksksm schrieb:

    Was machst Du wenn Du generelle Einstellungen ändern musst aber die aktuellen Einstellungen des Benutzers nicht ändern darfst ohne dass dieser Zustimmt?
    Keine Ahnung, in welcher Situation DerSmurf sich da befindet. Wenn das Programm das nicht darf, dann stellt sich die Frage, wie Du sicherstellst, dass das Programm keinen Zugriff auf die Daten des aktuellen Users erhält. Ich war in der Situation noch nicht, daher brauche ich (und ggf. DerSmurf) da Input, wie man es (besser/richtig) regelt.
    Oh, Schande! Ich hab tatsächlich die beiden Posts übersehen, die vor meinem kamen :S
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Ich habe keine Ahnung von den Möglichkeiten der EdR-Helpers, da ich sie nicht nutze.


    Da sind wir schon zwei^^
    Allerdings benutze ich kein VB.Net sondern C#. Ich kann aber nicht behaupten, dass das etwas am Schwierigkeitsgrad ändern würde. Grundsätzlich kannst du ein aber auch mehrere DataSets durch die Formen durchreichen.
    Deshalb meine Anmerkung überhaupt nur. Weil ich sehe auch "pur" also ohne Helper, keinen höheren Schwierigkeitsgrad ob ich nun ein oder mehrere tDS verwende.
    Nö, ich erkenne auf Anhieb da auch keine Probleme. Ich sehe, wir sind diesbezüglich auf einer Wellenlänge. Denn DerSmurf nutzt die Helpers. Und da steige ich mit meinem Wissen aus. Wie ich pur 2 tDS nutzen könnte, wüsste ich (entsprechend auch). Aber DerSmurf ist eben da in anderer Situation. Und eben da kann ich ihm nicht weiterhelfen. Da muss er sich schon an EdR wenden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Soho, ich klinke mich mal wieder ein und schwöre bei jedem Schreiben der Wörter DataTABLE und DataSET nochmal zu überlegen :o)

    Zu den Helpers vom EdR: Diese habe ich eingebunden ABER die einzigen beiden Funktionen die ich (bisher) hiervon nutze sind die Funktionen:
    EditCurrent und EditNew welche als Parameter eine Form verlangen.

    VB.NET-Quellcode

    1. If DTAddressbookBindingSource.Current Is Nothing Then Exit Sub
    2. DTAddressbookBindingSource.EditCurrent(Of frmEditAddress)

    Diese Form hat einen Cancel und einen OK Button und stellt letztlich einen Detailview der DataTable bzw der entsprechenden BindingSource dar.
    In meinen Textboxen, Comboboxen, oder was auch immer gebe ich die entsprechenden Werte ein, welche dann erst nach einem Klick auf den OK Button ins DataTable wandern und hier entweder alte Werte ändern (EditCurrent), oder einen neuen Eintrag erzeugen (EditNew).

    Den restlichen Zugriff und die Verarbeitung der Daten erledige ich ohne die Helpers. Also ich schätze (hoffe) mal so wie ihr auch.

    Dementsprechend werde ich auch mein zweites DataSet "normal" anbinden - hier habe ich jedoch noch keine Ahnung wie.
    Aber ich probiere und google erstmal, und präsentiere dann meine Lösung, oder schreihe nach Hilfe :)

    Das mit Einstellungen des aktuellen Benutzers nicht ändern dürfen und dergleichen entfällt bei meinem Programm.
    Der einzige Benutzers meines PCs bin ich.
    Wenn jemand anders mein Programm verwendet, dann entweder "in meinem Namen" (also meine Frau auf meinem PC, mit meinen Settings), oder jeweils auf einem eigenen Rechner.

    Edit: Ich bin verwirrt. Habe gerade das zweite DataSet erstellt und eingebungen. Testweise erstmal ohne Verschlüsselung, da ich mir sicher war auf Probleme zu stoßen, geht aber alles problemlos :o)
    So sieht der Datenlade und speicher Code der beiden DataSets aus (DataFile = xml für Daten / SettingsFile = xml für Einstellungen)

    VB.NET-Quellcode

    1. Private DataFile As New FileInfo(Application.StartupPath & "\data\Data.xml")
    2. Private SettingsFile As New FileInfo("SettingsFile.xml")
    3. Private Sub FrmMainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. 'DataSet laden
    5. If DataFile.Exists Then DtsMain.ReadXml(DataFile.FullName)
    6. End Sub
    7. Private Sub FrmMainForm_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    8. DtsMain.WriteXml(DataFile.FullName)
    9. End Sub
    10. 'Load und Save für die Settings sind erstmal in Buttons - ich weiß noch nicht wohin damit
    11. Private Sub Btnload_Click(sender As Object, e As EventArgs) Handles btnload.Click
    12. If SettingsFile.Exists Then DtsSettings.ReadXml(SettingsFile.FullName)
    13. End Sub
    14. Private Sub Btnsave_Click(sender As Object, e As EventArgs) Handles btnsave.Click
    15. DtsSettings.WriteXml(SettingsFile.FullName)
    16. End Sub


    Das sollte doch so korrekt sein oder?

    Dann mache ich mich jetzt mal an die Kryptografie...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DerSmurf“ ()

    Soho.
    @SpaceyX Vielen, vielen Dank für dein Demoprojekt. Mit dessen Hilfe habe ich nun erfolgreich eine verschlüsselte xml ersellt.
    Also wenn ich die xml meines Programmes öffne, wird mir kein Inhalt angezeigt, so wie in deinem Demoprojekt.
    Deswegen glaube ich zumindest es klappt :)
    Wie du aber wahrscheinlich vermutest, komme ich sehr gerne auf dein Angebot:
    Falls Du Fragen hast, einfach raus damit.
    zurück.
    Letzlich habe ich deinen Code eins zu eins übernommen und alle Controls (DGV und save und load Button) in meine TabPage "TPSettings" geschmissen.
    Eine Abfrage nach Masterpasswort habe ich noch nicht eingebunden.
    _masterPassword bleibt in meinem Programm einfach ein leerer String.
    So sieht das jetzt (erstmal) bei mir aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private SettingsFile As String = "SettingsFile.xml"
    2. Private _masterPassword As String = String.Empty
    3. Private Sub Btnload_Click(sender As Object, e As EventArgs) Handles btnload.Click
    4. If File.Exists(SettingsFile) Then
    5. Using cS As CryptoStream = GetDecryptionStream()
    6. Me.DtsSettings.ReadXml(cS)
    7. End Using
    8. End If
    9. End Sub
    10. Private Sub Btnsave_Click(sender As Object, e As EventArgs) Handles btnsave.Click
    11. If File.Exists(SettingsFile) Then File.Delete(SettingsFile)
    12. Using cS As CryptoStream = GetEncryptionStream()
    13. Me.DtsSettings.WriteXml(cS)
    14. End Using
    15. End Sub
    16. Private Function GetEncryptionStream() As CryptoStream
    17. Dim key As New Rfc2898DeriveBytes(_masterPassword, New Byte() {10, 255, 255, 7, 14, 16, 23, 155})
    18. Dim x As New TripleDESCryptoServiceProvider()
    19. Dim fS As FileStream = Nothing
    20. x.Key = key.GetBytes(x.KeySize \ 8)
    21. x.IV = key.GetBytes(x.BlockSize \ 8)
    22. fS = New FileStream(SettingsFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
    23. Return New CryptoStream(fS, x.CreateEncryptor(), CryptoStreamMode.Write)
    24. End Function
    25. Private Function GetDecryptionStream() As CryptoStream
    26. Dim key As New Rfc2898DeriveBytes(_masterPassword, New Byte() {10, 255, 255, 7, 14, 16, 23, 155})
    27. Dim x As New TripleDESCryptoServiceProvider()
    28. Dim fS As FileStream = Nothing
    29. x.Key = key.GetBytes(x.KeySize \ 8)
    30. x.IV = key.GetBytes(x.BlockSize \ 8)
    31. fS = New FileStream(SettingsFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
    32. Return New CryptoStream(fS, x.CreateDecryptor(), CryptoStreamMode.Read)
    33. End Function


    Hier möchte ich gerne die Passwortabfrage verschieben. Diese soll erscheinen, wenn ich auf den Laden Button klicke.
    Zusätzlich möchte ich aber auch wissen, wie das ganze ohne Master Password funktioniert - also es geht ja bei mir ohne Eingabe, aber ich brauche ja noch die _masterPassword Variable, da diese in GetDecryptionStream() und GetEncryptionStream() enthalten ist.
    Denn letzlich sperre ich beim Verlassen meines Rechners IMMER das System (Windows + L). Außerdem liegen meine Mailpasswörter solange ich den Thunderbird nutze ja eh blank auf der Platte (hier brauch ich ja nur in die Einstellungen zu gehen und auf Passwörter anzeigen zu klicken), wenn ich meinen PC mal nicht sperren sollte - was NIE passiert.
    Um das nachvollziehen zu können, habe ich ein paar Fragen zum Code deines Beispielprojektes, den ich nur zu 90% verstanden habe.

    1. Du importierst System.Text
    Meine IDE zeigt mir an, dass sei unnötig. Wenn ich diesen Import auskommentiere scheint das Programm anstandslos zu laufen.
    Wofür ist dieser Import gut?

    2. deine Onload Funktion:

    VB.NET-Quellcode

    1. Private _masterPassword As String = String.Empty
    2. Protected Overrides Sub OnLoad(e As EventArgs)
    3. Using mP As New MasterPassword()
    4. If mP.ShowDialog() = DialogResult.OK Then
    5. _masterPassword = mP.txtPassword.Text
    6. Else
    7. Close()
    8. End If
    9. End Using
    10. Try
    11. LoadData()
    12. Catch ex As Exception
    13. MessageBox.Show("Incorrect password")
    14. Close()
    15. End Try
    16. MyBase.OnLoad(e)
    17. End Sub


    Prinzipiell weiß ich was der Code tut. Du öffnest die Form MasterPassword und wertest die Button klicks aus. Wenn OK wird das eingegeben Passwort in _masterPassword gespeichert, sonst wirds Programm beendet.
    Im Try Catch Block, wird dann entweder das DataSet geladen, oder das Programm beendet.
    Also das Programm "versucht" LoadData() auszuführen. In LoadData wird, wenn die xml Datei existiert diese entschlüsselt und eingelesen.
    2.1 Also vermute ich, dass das Passwort in der xml Datei enthalten ist. Aber wie kommt das da rein?
    2.2 Was macht die letzte Zeile (MyBase.Onload(e)
    2.3 wenn ich das "normale" FormLoad Event verwende

    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    läuft das Programm unverändert. Warum Protected Overrides?

    3. Sowohl in der Verschlüsselung, als auch in der Entschlüsselung wird folgender Code verwendet:

    VB.NET-Quellcode

    1. Dim fS As FileStream = Nothing
    2. fS = New FileStream(_dataPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)

    Warum steht dies nicht in einer Zeile?

    VB.NET-Quellcode

    1. Dim fS As FileStream = New FileStream(_dataPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)


    4. Das wahrscheinlich wictigste: Ich verstehe weder die ver- noch die entschlüsselung. Könntest du diesen Code kommentieren?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DerSmurf“ ()

    DerSmurf schrieb:

    1. Du importierst System.Text


    Da hast Du Recht, ist nicht notwendig. Ich hab den Code aus Post #9 genommen, dort ist dieser nötig, da Encoding.UTF8.GetBytes(data) im System.Text-Namespace angesiedelt ist. Aber hier ist dieser nicht nötig.

    DerSmurf schrieb:

    2.1 Also vermute ich, dass das Passwort in der xml Datei enthalten ist. Aber wie kommt das da rein?


    Nein, das Passwort ist nirgendwo gespeichert. Wird das falsche Passwort eingegeben, dann schlägt die Entschlüsselung fehl und es wird eine Exception ausgelöst, welche im Catch-Block behandelt wird. Genauer müsste man es so machen:

    VB.NET-Quellcode

    1. Try
    2. LoadData()
    3. Catch ex As CryptographicException
    4. MessageBox.Show("Incorrect password")
    5. Close()
    6. End Try


    Das ist ein wichtiges Prinzip bei der Fehlerbehandlung, die Fehler nach ihrem Typ zu getrennt zu behandeln. War ein bisschen lasch von mir, aber viel mehr als ein falsches Passwort kann hier nicht passieren.

    DerSmurf schrieb:

    2.2 Was macht die letzte Zeile (MyBase.Onload(e)


    Mit Protected Overrides Sub OnLoad(e As EventArgs) überschreibe ich die Funktion der Basisklasse Form. Form1 erbt ja von Form. Diese Funktion löst das Event Form1_Load aus. Ist eine Angewohnheit von mir, Du kannst auch direkt das Event abonnieren, macht keinen Unterschied. Mit MyBase.OnLoad(e) wird dann einfach die entsprechende Funktion der Basisklasse Form aufgerufen. Die IDE fügt diesen Aufruf automatisch hinzu, sobald Du eine Funktion überschreibst. Wie gesagt, ist einfach eine Angewohnheit. Das sollte auch

    DerSmurf schrieb:

    2.3 wenn ich das "normale" FormLoad Event verwende


    beantworten.

    DerSmurf schrieb:

    3. Sowohl in der Verschlüsselung, als auch in der Entschlüsselung wird folgender Code verwendet:


    Kannst Du natürlich auch in einer Zeile machen. Hatte die Funktion zu Anfang anders strukturiert, was aber nicht geklappt hat. Hab einfach vergessen, dies zu ändern. Haste Recht, ganz klar.

    DerSmurf schrieb:

    4. Das wahrscheinlich wictigste: Ich verstehe weder die ver- noch die entschlüsselung. Könntest du diesen Code kommentieren?


    VB.NET-Quellcode

    1. Private Function GetEncryptionStream() As CryptoStream
    2. 'Rfc2898DeriveBytes ist eine Kombination aus dem Passwort und dem Salt.
    3. Dim key As New Rfc2898DeriveBytes(_masterPassword, New Byte() {10, 255, 255, 7, 14, 16, 23, 155})
    4. 'Erzeugung des Verschlüsselungs-Objects.
    5. Dim x As New TripleDESCryptoServiceProvider()
    6. 'Der Dateistrom in den der Cryptostream letztendlich schreibt.
    7. Dim fS As New FileStream(_dataPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
    8. 'Dem Verschlüsselungsobject wird das Passowrt zugewiesen, hier wird die Funktion GetBytes des Rfc2898DeriveBytes genutzt.
    9. 'Diese Funktion übernimmt als Argument die Anzahl an Bytes die generiert werden sollen. Der TripleDES-Alogrithmus hat eine
    10. 'Key-Länge von 192 Bits. 192 / 8 = 24 Byte. Also werden 24 Byte vom Rfc2898DeriveBytes-Object angefordert. Die zurück-
    11. 'gegebenen Bytes sind eine "Kombination" aus dem Passwort und dem Salt.
    12. x.Key = key.GetBytes(x.KeySize \ 8)
    13. 'IV = Initialisierungsvektor, welcher von der Blockgröße der gentutzen Verschlüsselung abhängt. Dient dazu, um mehr
    14. '"Chaos" zu erzeugen. Die Blockgröße hat bei TripleDES eine Größe vom 64 Bit. 64 / 8 = 8 Byte. Also werden 8 Byte
    15. 'Rfc2898DeriveBytes-Object angefordert.
    16. x.IV = key.GetBytes(x.BlockSize \ 8)
    17. 'Diese Funktion gibt einen Cryptostream zurück, welcher dann der DataSet-Methode "Write-XML, Read-XML" übergeben wird.
    18. Return New CryptoStream(fS, x.CreateEncryptor(), CryptoStreamMode.Write)
    19. End Function


    GetDecryptionStream ist dann analog dazu, außer dass ​CryptoStreamMode.Read verwendet wird. Wichtig zu verstehen ist, dass das Rfc2898DeriveBytes-Object bei der gleichen Passwort-Salt-Kombination beim Aufruf von GetBytes immer die gleichen Daten zurückliefert. Stimmt der Salt nicht, schlägt die Entschlüsselung fehl, stimmt das Passwort nicht, dann ebenso.

    DerSmurf schrieb:

    Hier möchte ich gerne die Passwortabfrage verschieben.


    Das bekommst Du bestimmt alleine hin, bin ich mir ganz sicher.


    DerSmurf schrieb:

    Zusätzlich möchte ich aber auch wissen, wie das ganze ohne Master Password funktioniert


    Dann bist Du leider wieder ganz am Anfang Deines Problems. Wenn Du kein Passwort hast, ist die ganze Verschlüsselungsorgie nicht sinnvoll.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Guten Morgen
    Vielen, vielen Dank für deine Mühe :)
    Vorab zum Passwort:
    Das es sinnbefreit ist, meine verschlüsselte Datei ohne passwortschutz zu hinterlegen, habe ich mittlerweile verstanden.
    Mir ging es hierbei um das verschieben der Passwortabfrage. Es ist natürlich kein Problem für mich, die Passwordabfrage zu verschieben, dass sie erscheint, wenn ich auf meinen Laden Button Klicke.
    Aber, Sinn und Zweck des ganzen ist es ja Email Zugangsdaten zu speichern.
    Wenn ich das Passwort nun ausschließlich in meinem Settings Lade Button Abfrage, bleibt meine Passwortvariable leer, wenn ich z.B. eine Email versende. Also scheint es für mich so, als wenn die Passwortabfrage nur zu Programmstart Sinn macht.
    Dies ist für mich aber unheimlich lästig - ich will nicht sagen NoGo - aber in der Praxis echt nervig.
    Nun stellt sich mir folgende Frage
    Was bringt es mir meine Mailpasswörter in meinem Programm mit einem Kennwort zu sichern, wenn jeder der Zugriff auf meinen PC bekommt auch ein anderes Programm öffnen kann, welches diese Passwörter eben ohne Passwortschutz bereithält (mein Thunderbird z.B.)

    Zur Verschlüsselung: Da kommt so langsam ein wenig LIcht ins dunkle :)
    Aber so ganz gerafft hab ich das nocht nicht. Mich macht das Passwort stutzig.
    In meiner oben geposteten Version bleibt das Passwort (-masterpassword) einfach leer, alles scheint trotzdem zu laufen.
    Wenn ich in deinem Testprogramm das Passwort leer lasse (also z.B: FormLoad auskommentiere), bekomme ich keinen Zugriff auf die Daten.
    Und was ich einfach nicht verstehe ist, woher weiß meine Verschlüsselung, welches Passwort korrekt ist?
    Also wenn du mir nicht das "password123" mitgeteilt hättest, würde ich doch am Code nicht erkennen was das korrekte Password ist.
    Das ist ja Sinn der Sache, aber woher "weiß" das Programm was stimmt und was nicht?
    Du sagtes in deinem letzten post, dass dann die Entschlüsselung fehlschlägt. Also muss ja das Passwort irgendwie mit dem Salt zusammenhängen. Muss ich also den Salt ändern, wenn ich ein anderes Passwort möchte?

    Und bitte entschuldige meine "Anfängerfragen" (Public Overrice FormLoad, den Import und die Deklaration).
    Ich wollte nur sichergehen den Code um die Verschlüsselung zu 100% verstanden zu haben.

    Edit: Eins noch.
    Du sagst "192 / 8 = 24 Byte" warum dividierst du durch 8?

    DerSmurf schrieb:

    Was bringt es mir meine Mailpasswörter in meinem Programm mit einem Kennwort zu sichern, wenn jeder der Zugriff auf meinen PC bekommt auch ein anderes Programm öffnen kann, welches diese Passwörter eben ohne Passwortschutz bereithält
    Dann kommen wir zum allerersten Post zurück:

    DerSmurf schrieb:

    Wie kann ich meine Maildaten sicher im Programm hinterlegen

    DerSmurf schrieb:

    woher weiß meine Verschlüsselung, welches Passwort korrekt ist?
    Deine Daten sind verschlüsselt. Wenn Du die Daten entschlüsseln willst, brauchst Du ein Passwort. Dann nimmt der Algorithmus Deine verschüsselten Daten, Passwort und Salt und "verrechnet" das Ganze miteinander. Die ganze Rechnung ist recht kompliziert, aber einfach ausgedrückt: Wenn man das falsche Passwort verwendet, ist das so, als ob man ne mathematische Berechnung hat, bei der dann rauskommt, dass man irgendwo durch Null teilt -> Fehler. Und dann weiß der Computer: Zugangsdaten waren falsch. Nur mit den korrekten Daten ikommt ein "richtiges Ergebnis" raus.
    Salt ergänzt das Passwort, um die Nutzung von Rainbow Tables zu erschweren, denen also die Suppe zu versalzen (daher der Begriff).
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Wenn du das MasterPassword nicht eingeben willst, wird die Sicherheit halt unterhöhlt.
    Aber ich kenne das Problem, dass so eine Eingabe dem User nicht zuzumuten ist.

    Für interne Anwendungen nehme ich dann meist eine Kombination von unauffälligen Dingen, die im Programm bereits vorhanden sind.
    Klassenname, URL...
    Du kannst auch im Passwort Environment-Variablen unterbringen (Username, Domain, ExecutionPath), dann kann nur dieser eine User entschlüsseln.

    Aber eine Reverse-Analyse des Programms deckt solche Dinge natürlich auf.
    Doch mal ehrlich: Dein Mailpasswort lässt sich unter Umständen einfacher durch einen Netzwerkanalyzer knacken, ohne tief in die Programmstrukturen zu gehen.
    Oder durch eine Memoryanalyse beim Absenden der Mail.

    Es stellt sich auch die Frage, was sicherer ist:
    Ein unauffälliges automatisches Passwort oder ein Masterpasswort, das du jedem Benutzer mitteilen musst und er dann als Zettel am Monitor hängen hat.
    Also: Ein Passwort, das keiner weiß oder ein Passwort, das jeder weiß?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „petaod“ ()

    Ihr seid genial! Da kann man garnicht oft genug Danke sagen :o)

    Also, der Ansatz von petaod gefällt mir.
    Für interne Anwendungen nehme ich dann meist eine Kombination von unauffälligen Dingen, die im Programm bereits vorhanden sind.
    Klassenname, URL...

    Das verstehe ich aber nicht. Passwort Environment Variablen habe ich noch nie gehört, da werde ich heute Abend mal googlen.
    Aber der Name lässt zumindest vermuten, dass dies die Lösung meines Problems sein könnte.

    Ich glaube das mit Passwort in der Verschlüsselung habe ich auch gerafft. Habe aber leider meinen Privat Laptop zuhause gelassen, daher kann ich nicht testen. Deswegen muss ich leider weiter nerven (Bin gerade spitz auf das Thema, wie Nachbars Lumpi, deswegen mag ich nicht bis heute Abend warten)
    Ich brauche zum entschlüsseln einfach das gleiche Passwort, wie zum verschlüsseln, dabei ist vollkomen wurscht, wie das Passwort lautet.
    Wenn ich also hier in der verschlüsselung _MasterPassword ersetze (oder eben dein Inhalt einer InputBox zuweise)

    VB.NET-Quellcode

    1. Private Function GetEncryptionStream() As CryptoStream
    2. Dim key As New Rfc2898DeriveBytes("StrengGeheimerPasswortString", New Byte() {10, 255, 255, 7, 14, 16, 23, 155})

    Dann macht natürlich die Verschlüsselung keinen echten Sinn mehr, aber zum entschlüssen brauche ich dann eben das Passwort
    "StrengGeheimerPasswortString" ?

    Hat @SpaceyX auf diese Art das "password123" in sein Beispielprojekt bekommen?

    Und ist meine xml Datei überhaupt korrekt verschlüsselt, wenn mir der internetExplorer keinen Inhalt anzeigt?

    DerSmurf schrieb:

    Passwort Environment Variablen habe ich noch nie gehört
    Ich auch nicht.
    Damit ist auch gemeint, dass du zur Laufzeit Umgebungsvariablen wie Rechnername, Benutzername usw. auslesen kannst und diese dann als Passwort verwenden.
    Aber wie gesagt, das muss reproduzierbar sein, da du zum Ver- und Entschlüsseln dasselbe Passwort verwenden musst.
    Wenn du also den Username in das Passwort integrierst, kann nur dieser User auch wieder entschlüsseln.

    DerSmurf schrieb:

    Und ist meine xml Datei überhaupt korrekt verschlüsselt, wenn mir der internetExplorer keinen Inhalt anzeigt?
    Klingt plausibel, dass der IE keine verschlüsselte Datei interpretieren kann.
    Im Editor siehst du, was daraus gemacht wurde.
    Wenn die komplette Datei verschlüsselt wird, also auch keine XML-Struktur mehr aufweist, würde ich sie aber auch nicht als .XML speichern.
    Ob die Verschlüsselung geklappt hat, merkst du daran, dass sie nach der Verschlüsselung kryptisch aussieht und du sie auch wieder entschlüsseln kannst.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Mahlzeit,

    DerSmurf schrieb:

    n meiner oben geposteten Version bleibt das Passwort (-masterpassword) einfach leer


    Du hast eben die Daten ohne Passwort und nur mit dem Salt verschlüsselt. Wie gesagt -> Rfc2898DeriveBytes liefert beim Aufruf von GetBytes eine zufällige Bytefolge auf Basis von beiden. Nur wenn beide gleich sind, werden die gleichen zufälligen Bytefolgen zurückgeliefert.

    DerSmurf schrieb:

    Also wenn du mir nicht das "password123" mitgeteilt hättest, würde ich doch am Code nicht erkennen was das korrekte Password ist.


    Genau. Die Entschlüsselung der Daten muss fehlschlagen, wenn das Passwort nicht stimmt. Rfc2898DeriveBytes liefert dann in Kombination mit dem Salt falsche Bytefolgen zurück.

    DerSmurf schrieb:

    aber woher "weiß" das Programm was stimmt und was nicht?


    Ich kenne den internen Ablauf der Ver- bzw. Entschlüsselung nicht. Das ist in der Klasse TripleDESCryptoServiceProvider implementiert. Hier wird wohl irgendwo eine IndexOutOfRange oder eine andere Exception auftreten. Genau kann ich Dir das nicht sagen. Was aber wichtig ist, dass diese Exception ausgelöst wird, wenn das Passwort, bzw. der IV nicht passt. Diese Ausnahme lässt sich dann fangen und entsprechend behandeln. Wenn es Dich interessiert, muss Du tiefer in Cryptopgraphy einsteigen. Hier fehlt mir persönlich das mathematische Verständnis.

    DerSmurf schrieb:

    Muss ich also den Salt ändern, wenn ich ein anderes Passwort möchte?


    Jein. Änderst Du den Salt und das Passwort bleibt gleich, ändert sich auch die Bytefolge beim Aufruf von GetBytes. Änderst Du das Passwort und der Salt bleibt gleich ist dies ebenso. Es ist immer die Kombination aus beiden. Bei der Entschlüsselung muss die Password-Salt-Kombination die selbe sein, die auch beim Verschlüsseln verwendet wurde. Das Passwort alleine kann die Daten nicht entschlüsseln.

    DerSmurf schrieb:

    Du sagst "192 / 8 = 24 Byte" warum dividierst du durch 8?


    1 Byte besteht aus 8 Bit. Beispiel die Dezimalzahl 156. In binär ist das -> 1001 1100. Gelesen wird von rechts nach links.

    0 hoch 1 = 0
    0 hoch 2 = 0
    1 hoch 4 = 4
    1 hoch 8 = 8
    1 hoch 16 = 16
    0 hoch 32 = 0
    0 hoch 64 = 0
    1 hoch 128 = 128

    Gibt in Summe 4+8+16+128=156.

    Da die KeySize des TripleDESCryptoServiceProvider-Algorithmus 192 Bit beträgt, musst Du 24 Bytes aus der Funktion GetBytes anfordern. 192 Bits / 8 = 24 Byte. Die KeySize ist 24 Byte lang. Die verschiedenen Zahlensysteme solltest Du bei Gelegenheit genauer anschauen, ist wirklich wichtig in der Programmierwelt.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Alles klar.
    Ich glaube dann habe ich es so langsam geschnallt.
    Dann ist nur noch meine eine Frage von oben offen.
    Wenn hier die Antwort ja lautet. Hab ichs wirklich gerafft :o)

    DerSmurf schrieb:

    Ich glaube das mit Passwort in der Verschlüsselung habe ich auch gerafft. Habe aber leider meinen Privat Laptop zuhause gelassen, daher kann ich nicht testen. Deswegen muss ich leider weiter nerven (Bin gerade spitz auf das Thema, wie Nachbars Lumpi, deswegen mag ich nicht bis heute Abend warten)
    Ich brauche zum entschlüsseln einfach das gleiche Passwort, wie zum verschlüsseln, dabei ist vollkomen wurscht, wie das Passwort lautet.
    Wenn ich also hier in der verschlüsselung _MasterPassword ersetze (oder eben dein Inhalt einer InputBox zuweise)
    VB.NET-Quellcode

    Private Function GetEncryptionStream() As CryptoStream
    Dim key As New Rfc2898DeriveBytes("StrengGeheimerPasswortString", New Byte() {10, 255, 255, 7, 14, 16, 23, 155})


    Dann macht natürlich die Verschlüsselung keinen echten Sinn mehr, aber zum entschlüssen brauche ich dann eben das Passwort
    "StrengGeheimerPasswortString" ?

    Hat @SpaceyX auf diese Art das "password123" in sein Beispielprojekt bekommen?

    DerSmurf schrieb:

    Hat @SpaceyX auf diese Art das "password123" in sein Beispielprojekt bekommen?


    Wenn das Deine Frage ist, lautet die Antwort. Ich habe die Datei mit dem Passwort password123 verschlüsselt, nichts weiter.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Um noch mehr Klarheiten zu beseitigen, hier auch mein Senf dazu: Du hast nen Klartext. Das ist zum Anfang die erste Komponente (K1). Dann kommen Passwort und Salt, K2 und K3. All diese 3 Komponenten legst Du zum Anfang selber fest. Aus diesen dreien errechnet der Verschlüsselungsalgorithmus einen verschlüsselten Text, irgend ein Byte-Kuddelmuddel. Und dieses Byte-Kuddelmuddel lässt sich später mit K2 und K3 wieder zu K1 machen. Wenn Du K1 wieder hast (also wieder Klartext), kannst Du auch ein neues Passwort und neues Salt verwenden, um wieder ein Byte-MKuddelmuddel zu bekommen. Aber dann kommt natürlich ein anderes raus als mit Passwort 1 und Salt 1. (Sonst wär's ja auch sinnlos.)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Jo, ich glaube dann habe ich es.
    Wenn ich also etwas verschlüsseln möchte, mit einem Passwort, dass sich der User aussuchen kann sähe das so aus:

    VB.NET-Quellcode

    1. Private pw as string = ""
    2. Private Sub pwanlegen()
    3. pw = InputBox("Bitte pw eingeben")
    4. End sub
    5. Private Function GetEncryptionStream() As CryptoStream
    6. Dim key As New Rfc2898DeriveBytes(pw, New Byte() {10, 255, 255, 7, 14, 16, 23, 155})


    Bitte sagt, das stimmt so (nicht auf die Input Box Syntax achten bitte), dann habe ich es nämlich gerafft.