Daten in SQL Server verschlüsseln und entschlüsseln

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Montoyafan.

    Daten in SQL Server verschlüsseln und entschlüsseln

    Hallo Allerseits!
    Ich mal wieder. ?(
    Ich hänge immer noch an meinem Projekt eine Form zu erschaffen, die 1:1 wie eine Datenbank ist, aber für Leute die kaum/keine Ahnung haben vom programmieren diese Form Anfängerfreundlich bedienen können.
    Nun wurde mir gesagt das ich einen Schritt weiter wagen soll, ich soll Passwörter (die per Zufall generiert werden) Verschlüsselt in die Datenbank speichern, die Datenbank sieht man in einem DataGridView auf der Form.
    Im DataGridView sollen die Passwörter aber entschlüsselt da stehen. (naja es soll statt dem Passwort üblicherweise Sternchen stehen, aber das ist nicht das Problem was ich ebend habe)
    Wenn ein Kunde die Form öffnet, soll man sich auch nicht anmelden.
    Mir wurde gesagt das ich für das verschlüsseln und entschlüsseln Blowfish(BCrypt.net) nehmen soll, aber ich habe die Passwörter als Hash abgespeichert, aber einen Hash kann man ja nicht entschlüsseln (also schon, aber das dauert EWIG)
    Als nächstes wurde mir gesagt ich solle doch bitte einen MasterKey entwickeln, aber wofür nützt mir der MasterKey etwas, wenn ich nicht einmal das verschlüsselte entschlüsselt bekomme.
    Und hier benötige ich nun Hilfe. Ich will kein Vorgekauten Code für so etwas haben, ich möchte das mir vielleicht jemand sagen kann auf was ich achten muss, was für Bestandteile ich brauche.
    Ich stehe auf den Schlauch und meine Ausbilder können mir Leider nicht wirklich was dazu sagen, da sie mit anderen Dingen beschäftigt sind.
    Um ehrlich zu sein glaub ich, dass die sowas auch nur einmal gemacht haben und dass dann nie wieder gebraucht haben.
    Ich bedanke mich schonmal für Antworten! :thumbsup:

    Nun Folgen die Formen die betroffen sein sollen:
    Bilder
    • Passwort Generator 06.01.2023 14_08_22.png

      10,8 kB, 806×446, 82 mal angesehen
    • Hinzufügen von Benutzer 06.01.2023 14_09_00.png

      11,61 kB, 694×511, 82 mal angesehen
    Wenn Du den Hashwert von etwas erstellen lässt, hast Du erstmal Datensalat*.
    Wenn Du erneut den Hashwert von jenem Etwas ermittelst, kommt der gleiche Datensalat raus.
    Damit weißt Du, dass beim ersten und zweiten Mal das gleiche Etwas gehasht wurde.
    Aus dem Datensalat das Etwas wiederherzustellen ist nicht gewollt und nicht Sinn der Sache.

    Wenn Du ein Etwas verschlüsselst, brauchst Du (mindestens) einen Schlüssel. Du bekommst dann auch einen Datensalat. Jenen Schlüssel verwendest Du auch, um aus dem Datensalat wieder jenes Etwas zu bekommen.

    Hashen und Schlüssel verwenden sind also zwei Paar Wintersocken.

    Wenn Du jetzt aber einen Schlüsselanwendungsalgorithmus (also zum Ver- und Entschlüsseln) verwendest und dieser keinen MasterKey benötigt, kann ein Codewiesel den Algo rausbekommen und Deine Schlüsselbenutzung umgehen. Und damit ist nix mehr sicher. Daher der MasterKey, der dafür sorgt, dass das Ganze sicher ist.

    * der Datensalat wird - abhängig von der Situation - wahrscheinlich als Zeichensalat dargestellt, aber das ist nebensächlich.
    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.
    Der erste Schritt wäre Funktionen z.B. in Blowfish/BCrypt.net zu finden, die für das Ver- und Entschlüsseln verwendet werden. Die Verschlüsselungsfunktion sollte das zu verschlüsselnde Etwas und einen Key entgegen nehmen und Datensalat ausspucken. Und dieser Datensalat sollte in die Entschlüsselungsfunktion gesteckt werden, zusammen mit dem Key und das ursprüngliche Etwas sollte wieder rauskommen. Da ich Blowfish/BCrypt nicht verwende, musst Du also in die Doku schauen.
    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.
    Ich hab mal was kleines zusammengebaut:

    Quellcode

    1. Dim hashedPassword As String = BCrypt.Net.BCrypt.HashPassword(password)
    2. command.CommandText = "INSERT INTO Datenbank (username, password) VALUES (@username, '" & hashedPassword & "')"
    3. command.Parameters.AddWithValue("@username", username)
    4. command.Parameters.AddWithValue("@password", password)
    5. command.ExecuteNonQuery()


    geht das denn schon in die richtige Richtung?
    Eh, nee.
    Ich dächt ich hätte den Unterschied zwischen Hashen und Verschlüsseln klargemacht. Wenn Du Texte wie Passwörter verschlüsselt speichern, aber im GUI entschlüsselt anzeigen lassen willst, kannst Du nicht mit Hashing arbeiten. Von Datenbank hab ich auch nix geschrieben.
    Dein Code sollte erstmal sowas sein:

    VB.NET-Quellcode

    1. Dim Datensalat = Verschlüsselungsfunktion(IrgendeinText, Passwort)
    2. Dim Ergebnis = Entschlüsselungsfunktion(Datensalat, Passwort)
    3. If Ergebnis = IrgendeinText Then
    4. MessageBox.Show("Ver- und Entschlüsseln klappt.")
    5. Else
    6. MessageBox.Show("Ver- und Entschlüsseln hat NICHT klappt.")
    7. End If

    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.

    JoJo129 schrieb:

    Ich hänge immer noch an meinem Projekt eine Form zu erschaffen, die 1:1 wie eine Datenbank ist, aber für Leute die kaum/keine Ahnung haben vom programmieren diese Form Anfängerfreundlich bedienen können.
    Das ergibt in meinen Augen keinen Sinn.
    Ein Form kann nicht 1:1 wie eine Datenbank sein.
    Und eine Datenbank kann man nicht anfängerfreundlich bedienen - eiglich kann man sie garnet bedienen.

    Du kannst ein Programm schreiben, zu irgendeinem Zweck.
    Vielleicht ists nützlich, dieses Programm mit einer Datenbank auszustatten.
    Es ist möglich, Programme zu schreiben, die ihren Zweck auf benutzerfreundliche Weise erfüllen.

    Aber ohne einen Zweck kann man kein Programm schreiben, schon gar kein "anfängerfreundliches".

    Was ist der Zweck deines Programms?
    Da eine Datenbank keine Mitarbeitsliste erstellen kann, ist die Aussage

    JoJo129 schrieb:

    wie bei einer Datenbank
    plan-/sinnlos.
    Kannst Du inzwischen ein Codebeispiel wie in Post#6 bei Dir funktional nachbauen? Ganz ohne Datenbankgefummel.
    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:

    Kannst Du inzwischen ein Codebeispiel wie in Post#6 bei Dir funktional nachbauen? Ganz ohne Datenbankgefummel.

    Nein kann ich noch nicht, weil immer der gleiche Fehler kommt.
    Das Passwort wird verschlüsselt, aber nicht entschlüsselt.
    Ich habe auch schon mehrere verschiedene Methoden probiert, um die Passwörter zu ver-/entschlüsseln, aber ohne Erfolg.
    Deines Funktionsnamens nach handelt es sich hierbei nicht um eine Ver-/Entschlüsselung sondern um eine Hashfunktion. Der Unterschied sollte dir klar sein, wenn du damit arbeitest.

    Hashfunktionen sind sogenannte Einwegfunktionen. Du kannst einen Wert hashen, aber nicht wieder "enthashen". Der Wert bleibt dann in deiner Teminologie "verschlüsselt".

    Ein Hash hat folgende Eigenschaften:
    - er ist einzigartig
    - unabhängig vom Input kommt immer eine Zeichenkette mit identischer Zeichenlänge raus
    - Wenn man zweimal das gleiche durch die Hashfunktion schickt, dann erhält man beide Male den gleichen Hashwert
    - Hashfunktionen funktionieren nur in eine Richtung
    - Das Verändern eines einzelnen Zeichens im Klartext sorgt dafür, dass ein komplett anderer Hashwert erzeugt wird

    Wenn du jetzt also ein Passwort hasht und in die Datenbank schreibst, dann ist nicht vorgesehen, dass das jemals wieder in Klartext gewandelt wird. Wenn man einen Abgleich machen will, dann wird der Wert, der verglichen werden soll, durch die gleiche Hashfunktion gedrückt und es werden die Hashwerte miteinander verglichen, nicht die Klartext-Passwörter.

    Das Rückwandeln der Passwörter in Klartext erfolgt ausschließlich über (systematisches) Ausprobieren. Hierfür nutzt man in der Regel sogenannte Rainbow-Tables die Millionen von Hashwerten und die dahinterliegenden Passwörter enthalten. Die Rainbowtables findet man im Internet, kann man aber auch relativ einfach selbst erstellen. Um sensible Daten wie Passwörter gehasht abzulegen, muss man also gegen diese Rainbow-Tables entsprechende Maßnamen treffen. Die einfachste Variante hierfür sind sogenannte Salts. Das sind im Bestfall autogenerierte Zeichenketten, die mitgehasht werden und dadurch einen ganz anderen Hashwert zu einem Passwort erzeugen. Damit werden allgemeine Rainbow-Tables nutzlos gegen deine Hashfunktion.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

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

    Dann musst du mir die Diskrepanz zwischen Post#5 und Post#10 erläutern. In Post#5 testest du eine Hashfunktion und in Post#10 schreibst du darüber, dass sich das Passwort nicht entschlüsseln lässt?

    Welchen Ansatz verfolgst du denn aktuell?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    Ich habe das Gefühl das die Verwirrung daher kommt, dass er Blowfish(BCrypt.net) verwenden soll.
    BCrypt.net ist aber nur zum hashen von Passwörtern und nicht zum verschlüsseln. Daher wirst in dem Package auch nix zum verschlüsseln finden.
    Das ist ja die Umsetzung von bcrypt und das ist eine Hashfunktion.

    Daher solltest du schauen wie du Blowfish verwenden kannst in C#, denn damit kann man auch ver und entschlüsseln. (Bouncy Castle wird das sicher haben)
    Das ist meine Signatur und sie wird wunderbar sein!

    JoJo129 schrieb:

    Das zum Thema hashen wusste ich schon ...

    Das wage ich zu bezweifeln ! :/
    Wenn dir hier effektiv geholfen werden soll, ist es nicht sinnvoll, aufgrund irgendwelcher Eitelkeiten, deine wahren Fähigkeiten zu verschleiern. ;)
    Also ich hab die letzten Tage weiterhin rumrecherchiert, aber immer noch ohne Erfolge.
    Bei meinem letzten "Codeversuch" wurde das Passwort einfach in Chinesisch übersetzt 8|
    Da mir nichtmal mein Ausbilder dabei helfen kann, werd ich nun einen anderen Weg suchen, um das richtige Passwort woanders abzuspeichern und das verschlüsselte Passwort in meine Datenbank abspeicher.
    In dem Falle könnte ich sogar das Passwort Hashen, meint Ihr nicht auch?
    Trotzdem Danke für eure Hilfe! :thumbsup:
    Warum soll das Kennwort wieder entschlüsselt werden?

    Für normale Anwendungen gilt: In eine Datenbank sollte man nie Kennworte im Klartext noch verschlüsselt ablegen. Die Passphrase sollte immer gehashed, besser ein salted hashed sein. Bei der Überprüfung wird das eingegeben Kennwort wieder gehashed und der gehashed Wert wird mit dem in der DB hinterlegten Wert abgeglichen.

    Falls Du eine Password-Manager entwickeln willst, schau dir den Code von keepass (github.com/dlech/KeePass2.x) an.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Hallo,




    VB.NET-Quellcode

    1. ​Imports System.IO
    2. Imports System.Security.Cryptography
    3. Imports System.Text
    4. Public Class Form1
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. Dim strCrypt As String = txtPassword.Text
    7. lblEncrypt.Text = Encrypt(strCrypt)
    8. lblDecrypt.Text = Decrypt(lblEncrypt.Text)
    9. End Sub
    10. Private Function Encrypt(clearText As String) As String
    11. 'EncryptionKey - mit diesem Schlüssel wird der Datensatz ver- und entschlüsselt.
    12. 'Muss in beiden Funktion gleich sein!
    13. Dim EncryptionKey As String = "$kldfKFSAK37236780!!*+++hHUDO723BNU!$hask+*jhds7!2929j$+jP*!hWrT$kldfKFSAK37236780!!*+++hHUDO723BNU!$hask+*jhds7!2929j$+jP*!hWrT"
    14. Dim clearBytes As Byte() = Encoding.Unicode.GetBytes(clearText)
    15. Using encryptor As Aes = Aes.Create()
    16. Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76})
    17. encryptor.Key = pdb.GetBytes(32)
    18. encryptor.IV = pdb.GetBytes(16)
    19. Using ms As New MemoryStream()
    20. Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
    21. cs.Write(clearBytes, 0, clearBytes.Length)
    22. cs.Close()
    23. End Using
    24. clearText = Convert.ToBase64String(ms.ToArray())
    25. End Using
    26. End Using
    27. Return clearText
    28. End Function
    29. Public Function Decrypt(cipherText As String) As String
    30. 'EncryptionKey - mit diesem Schlüssel wird der Datensatz ver- und entschlüsselt.
    31. 'Muss in beiden Funktion gleich sein!
    32. Dim EncryptionKey As String = "$kldfKFSAK37236780!!*+++hHUDO723BNU!$hask+*jhds7!2929j$+jP*!hWrT$kldfKFSAK37236780!!*+++hHUDO723BNU!$hask+*jhds7!2929j$+jP*!hWrT"
    33. Dim cipherBytes As Byte() = Convert.FromBase64String(cipherText)
    34. Using encryptor As Aes = Aes.Create()
    35. Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76})
    36. encryptor.Key = pdb.GetBytes(32)
    37. encryptor.IV = pdb.GetBytes(16)
    38. Using ms As New MemoryStream()
    39. Using cs As New CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)
    40. cs.Write(cipherBytes, 0, cipherBytes.Length)
    41. cs.Close()
    42. End Using
    43. cipherText = Encoding.Unicode.GetString(ms.ToArray())
    44. End Using
    45. End Using
    46. Return cipherText
    47. End Function
    48. End Class


    Gruß