decrypten => Encrypten

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von GOKTerek.

    decrypten => Encrypten

    Guten Morgen,

    ich muss aktuell ein Login für unser ERP-System Temporär Lokal speichern. Das möchte ich natürlich nicht Lesbar machen, also war die Idee, die Anmeldaten sowie einige andere Informationen Gecryptet abzulegen.
    Hierzu habe ich einen Code aus dem Internet genommen und Modifiziert. Jedoch treten hier zwei Probleme auf.

    Code Decrypten:

    VB.NET-Quellcode

    1. Public Function DecryptString(ClearString As String, Optional ByVal CryptingString As String = "TESTPWFUERDASHIER") As String
    2. Dim ReturningString As String
    3. Try
    4. Dim ClearBytes As Byte() = Encoding.UTF8.GetBytes(ClearString)
    5. Using EnCryptor As Aes = Aes.Create()
    6. Dim pdb As New Rfc2898DeriveBytes(CryptingString, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76})
    7. EnCryptor.Key = pdb.GetBytes(32)
    8. EnCryptor.IV = pdb.GetBytes(16)
    9. Using ms As New MemoryStream()
    10. Try
    11. Using cs As New CryptoStream(ms, EnCryptor.CreateDecryptor, CryptoStreamMode.Write)
    12. cs.Write(ClearBytes, 0, ClearBytes.Length)
    13. cs.Close()
    14. End Using
    15. Catch ex As Exception
    16. Debug.Print(ex.Message & vbNewLine & ex.StackTrace) ' Hier springt er raus
    17. End Try
    18. ReturningString = Encoding.Unicode.GetString(ms.ToArray())
    19. Dim teststring As String = EncryptString(ReturningString)
    20. Debug.Print(teststring)
    21. End Using
    22. End Using
    23. Catch ex As Exception
    24. Debug.Print(ex.Message & vbNewLine & ex.StackTrace)
    25. End Try
    26. Return ReturningString
    27. End Function


    Hier springt er bei cs.close raus mit der Meldung: Die Eingabedaten sind kein vollständiger Block.

    Hier der Encrypting Code:

    VB.NET-Quellcode

    1. Public Function EncryptString(ClearString As String, Optional ByVal CryptingString As String = "TESTPWFUERDASHIER") As String
    2. Dim ReturningString As String
    3. Dim ClearBytes As Byte() = Encoding.Unicode.GetBytes(ClearString)
    4. Using EnCryptor As Aes = Aes.Create()
    5. Dim pdb As New Rfc2898DeriveBytes(CryptingString, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76})
    6. EnCryptor.Key = pdb.GetBytes(32)
    7. EnCryptor.IV = pdb.GetBytes(16)
    8. Using ms As New MemoryStream()
    9. Try
    10. Using cs As New CryptoStream(ms, EnCryptor.CreateEncryptor(), CryptoStreamMode.Write)
    11. cs.Write(ClearBytes, 0, ClearBytes.Length)
    12. cs.Close()
    13. End Using
    14. Catch ex As Exception
    15. End Try
    16. ReturningString = Encoding.UTF8.GetString(ms.ToArray())
    17. End Using
    18. End Using
    19. Return ReturningString
    20. End Function


    Hier kommt dann natürlich Teilweise Kauderwelschraus:

    Input:
    "GOKTest_11;_;MAIN;_;G656.int.test.de:59999;_;Michael;_;Das_888_ist ein_PW"

    Output:
    GOKTest_11;_;MAIN;_;G656.int.test.de:59999�h�" & ChrW(14) & "pX���V" & ChrW(127) & "�@�^g

    Ich finde leider keine Lösung warum er bei CS.Close rausspringt. habt Ihr eine Idee

    die Farbe Rot ist der Moderation vorbehalten und wurde ersetzt ~VaporiZed

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

    Das Encoding muss schon in beiden Zeilen Dim ClearBytes As Byte() = Encoding.XXX.GetBytes(ClearString) gleich sein. Unicode ist nicht gleich UTF8.
    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.
    @GOKTerek Wenn das temporär und lokal ist, geht vielleicht auch diese einfache Methode:
    Einfache Methode um String zu verschlüsseln
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das weiss ich. Daran liegt es nicht, da ich das auch dachte, so ist das richtig(Habe hier echt alle varianten getestet und die ist das beste ergebniss).

    in beiden Funktionen Unicode bei Bytes sowie Decrypting und Encrypting:
    GOKTest_頧셟愢퇩횒怆̰㬋㕍탱橸ꮐ韁䢪焿銏뗴" & vbBack & "នﶩফ涔�驅痁젊鼦歷ⶰ㑻폇樽쮘⦟긗逇䂹冿弔㿧紜뒇㯜ﰵ큾倽鐣鲈⨰纶䪅䖁躻框阉㲥隵︿婵鲓屼

    Hier wenn ich beides auf UTF8 setze:
    h�Y�狺$�b���b�x���U�" & vbNullChar & ChrW(24) & "�W4i�" & ChrW(31) & "��3" & ChrW(27) & "Tk�$" & ChrW(2) & ChrW(5) & "Ŋ�����Q" & vbCr & "o�*b���Ky_��2&��" & ChrW(16) & "J�LM���F��mҵE��4�" & vbFormFeed & "��f�c��>" & ChrW(21) & "bC

    Ausserdem muss du beim Encoding rückwärtsdenken, glaube ich bitte korigiert mich:

    Decoding:
    UTF8 => Decoding => UniCode

    Encoding:
    Unicode => Encoding => UTF8

    Laut dem Link, haben die das auch so gemacht:
    aspsnippets.com/Articles/Encry…on-using-C-and-VBNet.aspx

    Ich kann aber keinen FromBase64string nehmen, da ich sonderzeichen habe.

    Es liegt wirklich am CS.Close (bei Decrypten) er bricht an der stelle ab, warum kann ich nicht sagen?

    @RodFromGermany

    Interessant, also meinst du ich soll es gar nicht so kompliziert machen! Die Logindaten werden ca. 24 std. gespeichert, da ich eine einmalige Tagesanmeldung in meinem Programm einbauen möchte.Das wird aus Technischen gründen, leider das Endergebniss sein. Das Login soll in ein Addin rein, das in einem Externen PDM-System eingebaut wird. Das dumme dabei ist, das PDM-System lädt das Addin 2x ein, die Sepperat laufen.Damit der User sich jetzt nicht 2 anmelden muss, hatte ich das als Lösung gedacht.

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

    GOKTerek schrieb:

    also meinst du ich soll es gar nicht so kompliziert machen
    Was sagt denn die Aufgabenstellung?
    Was sagt Dein Chef?
    Soll es nur vor "Schnell mal Hinsehern" geschützt werden?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich bin mein eigener Chef, habe in der hinsicht niemanden der über mir steht, da ich der einzige Programmierer bei uns bin. Es geht mir eher um die IT um Ihnen etwas Sicherheit zu geben.

    Aber ich habe deinen Code getestet und halte Ihn für sicher.
    Du kannst den string der da rauskommt nicht ohne den richtigen Key Entschlüssen.

    VB.NET-Quellcode

    1. Public Function DecryptString(ClearString As String) As String
    2. Dim ClearBytes As Byte() = Encoding.UTF8.GetBytes(ClearString).Select(Function(b, i) b Xor _Key(i Mod _Len)).ToArray
    3. Dim teststring As String = Convert.ToBase64String(ClearBytes)
    4. Dim teststring2 As String = EncryptString(teststring)
    5. Return teststring
    6. End Function
    7. Public Function EncryptString(ClearString As String) As String
    8. Dim Clearbytes As Byte() = Convert.FromBase64String(ClearString)
    9. Dim Teststring As String = Encoding.UTF8.GetString(Clearbytes.Select(Function(b, i) b Xor _Key(i Mod _Len)).ToArray)
    10. Return Teststring
    11. End Function


    Die Teststrings sind natürlich nur zum anschauen da :-).

    Im Endeffekt weiß ja niemand das die Datei existiert.

    EDIT: Hier der verbesserte Code mit Allgemeinen PW:

    VB.NET-Quellcode

    1. Public Function DecryptString(ClearString As String, Optional ByVal CryptingString As String = "Dasschreibe ich besteimmt hier nicht rein") As String
    2. Dim _Key() As Byte = Encoding.UTF8.GetBytes(CryptingString)
    3. Dim _Len As Integer = _Key.Length
    4. Dim ClearBytes As Byte() = Encoding.UTF8.GetBytes(ClearString).Select(Function(b, i) b Xor _Key(i Mod _Len)).ToArray
    5. Dim teststring As String = Convert.ToBase64String(ClearBytes)
    6. Dim teststring2 As String = EncryptString(teststring)
    7. Return teststring
    8. End Function
    9. Public Function EncryptString(ClearString As String, Optional ByVal CryptingString As String = "Dasschreibe ich besteimmt hier nicht rein") As String
    10. Dim _Key() As Byte = Encoding.UTF8.GetBytes(CryptingString)
    11. Dim _Len As Integer = _Key.Length
    12. Dim Clearbytes As Byte() = Convert.FromBase64String(ClearString)
    13. Dim Teststring As String = Encoding.UTF8.GetString(Clearbytes.Select(Function(b, i) b Xor _Key(i Mod _Len)).ToArray)
    14. Return Teststring
    15. End Function


    Anbei das Ergebniss, mit 2 Unterschiedlichen Keys(PW) generiert.
    EwoYADUkMgp0Y38eaAUIDBxvOkgcQkFDQAl7aiBkZmNoPCsmaiY8I2chN25RS0QOBRwIbG8RNiY1PH0KfhssJD0tCCMTC1JEQw==
    EwoYADUkMgp0Y38eaAUIDBxvGmg8JCM2Jn99azJjfn1rOzoxfTM/PGgxIGhweWNweWppC34HMSIyLW4aaQ0pNiYsBDQVGmRjZw==

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

    Falls AES statt Xor: hier ein Codeschnipsel
    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.
    Warum so kompliziert?

    Verschlüsseln:

    C#-Quellcode

    1. byte[] data = Cryptography.Aes256Encrypt(Encoding.UTF8.GetBytes(inputString), "SuperSecurePassword", Encoding.UTF8.GetBytes("SALT************"));
    2. File.WriteAllBytes(path, data);


    Entschlüsseln:

    C#-Quellcode

    1. byte[] data = File.ReadAllBytes(path);
    2. string outputString = Encoding.UTF8.GetString(Cryptography.Aes256Decrypt(data, "SuperSecurePassword", Encoding.UTF8.GetBytes("SALT************")));
    @slice habe die Aes256Encrypt bzw. Aes256Decrypt Funktion in Cryptography nicht gefunden !?! :(
    @Fakiz das mit dem FromBase64String bzw. ToBase64String funktioniert nicht da ich sonderzeichen in dem zu Cryptenden Text habe.

    @RodFromGermany ich denke deine Lösung wird so erstmal reichen, da ich mit der Keyverschlüsselung viele Optionen habe, um das ganze sehr sicher abzulegen. :)

    An alle nochmal Danke! Top!!!
    Autsch, sorry da habe ich mich selbst verarscht :D
    Total vergessen, das das eine selbstgeschriebene Methode ist

    Spoiler anzeigen

    C#-Quellcode

    1. /// <summary>
    2. /// Encrypts an array of bytes.
    3. /// </summary>
    4. /// <param name="bytesToBeEncrypted">An array of bytes that will be encrypted.</param>
    5. /// <param name="passwordBytes">The password used to derive the key.</param>
    6. /// <param name="salt">The key salt used to derive the key.</param>
    7. /// <returns></returns>
    8. public static byte[] Aes256Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes, byte[] salt)
    9. {
    10. byte[] encryptedBytes = null;
    11. using (MemoryStream ms = new MemoryStream())
    12. {
    13. using (RijndaelManaged aes = new RijndaelManaged())
    14. {
    15. aes.KeySize = 256;
    16. aes.BlockSize = 128;
    17. Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(passwordBytes, salt, 1000);
    18. aes.Key = key.GetBytes(aes.KeySize / 8);
    19. aes.IV = key.GetBytes(aes.BlockSize / 8);
    20. aes.Mode = CipherMode.CBC;
    21. using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
    22. {
    23. cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
    24. cs.Close();
    25. }
    26. encryptedBytes = ms.ToArray();
    27. }
    28. }
    29. return encryptedBytes;
    30. }
    31. /// <summary>
    32. /// Decrypts an array of bytes
    33. /// </summary>
    34. /// <param name="bytesToBeDecrypted">An array of bytes that will be decrypted.</param>
    35. /// <param name="passwordBytes">The password used to derive the key.</param>
    36. /// <param name="salt">The key salt used to derive the key.</param>
    37. /// <returns></returns>
    38. public static byte[] Aes256Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes, byte[] salt)
    39. {
    40. byte[] decryptedBytes = null;
    41. using (MemoryStream ms = new MemoryStream())
    42. {
    43. using (RijndaelManaged aes = new RijndaelManaged())
    44. {
    45. aes.KeySize = 256;
    46. aes.BlockSize = 128;
    47. Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(passwordBytes, salt, 1000);
    48. aes.Key = key.GetBytes(aes.KeySize / 8);
    49. aes.IV = key.GetBytes(aes.BlockSize / 8);
    50. aes.Mode = CipherMode.CBC;
    51. using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
    52. {
    53. cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
    54. cs.Close();
    55. }
    56. decryptedBytes = ms.ToArray();
    57. }
    58. }
    59. return decryptedBytes;
    60. }


    Edit: Ich seh gerade, ich sollte die Methoden mal updaten:
    The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.

    Heißt also einen der anderen Konstruktor zu benutzten, der System.Security.Cryptography.HashAlgorithmName unterstützt.
    Link: public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations, System.Security.Cryptography.HashAlgorithmName hashAlgorithm)

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

    GOKTerek schrieb:

    das mit dem FromBase64String bzw. ToBase64String funktioniert nicht da ich sonderzeichen in dem zu Cryptenden Text habe.
    Der Base64String kommt aber erst später zum Einsatz. TextMitSonderzeichen -> Bytes -> Base64 -> Bytes -> TextMitSonderzeichen.
    Die Base64-Variante funktioniert mit Sonderzeichen im Klartext daher problemlos. Ich habe die Post#7-Variante seit Jahren im Einsatz, und Sonderzeichen en masse.
    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.
    EDR du hast schon recht, der Base64Codierung ist es egal, was für Zeichen da kommen, solange sie in bytes sind. Sofern wirklich Sonderzeichen im Klartext also drin sind, ist es einfach empfehlenswert zuerst UTF8- oder Unicode-Encoding zu verwenden.

    Für die AES-Verkryptung (auch Rijndael) gibt es übrigends auch noch die Möglichkeit über TransformFinalBlock zu gehen, dann muss nicht auf Stream gewechselt werden, sondern die Byte-Array kann direkt verwendet werden.

    Freundliche Grüsse

    exc-jdbi

    EDIT: @GOKTerek Damit meinte ich eigentlich, das in deinem Beitrag #1 in Zeile 29 in der Methode EncryptString eine Base64Codierung kommen sollte, sofern du wirklich einen String am Schluss willst der keine Sonderzeichen enthält.In der Methode DecryptString in Zeile 7 muss dann eine Base64Decodierung angewendet werden. Am Schluss dieser Methode sollte mit einer UniCode-Encoding zu String dein ursprünglicher String wieder entstehen. Dein obiger Code sollte eigentlich klappen.

    Konnte es leider nicht testen, da ich kein VS auf diesem System habe.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „exc-jdbi“ ()

    GOKTerek schrieb:

    FromBase64string gibt bei einigen Zeichen Fehler aus.
    Das bedeutet, dass der übergebene String kein Base64string ist.
    Die Argumentation wäre dann korrekt, wenn ToBase64string diesen fehlerhaften String liefern würde.
    Hast Du dafür ein Beispiel?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Nein, da ich ja immer erst Crypte. ToBase64string würde ja im zwischenschritt beim Encodyng funktionieren. Da brauchen wir, auch nicht zu diskutieren :-).
    Nur wollte ich nochmal expliziet darauf hinweisen(falls jemand neues, dieses Thema liest), das beim ersten decrypten vorzugsweise UTF8.GetBytes(String) genommen wird, denn in vielen bsp. wird für den ersten Schritt im Decrypten FromBase64String im Code genommen(falls User ein example im Internet findet und probs hat). :)