3-dimensionales String-Array umwandeln in "hier könnte Ihre Lösung stehen"?

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

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    3-dimensionales String-Array umwandeln in "hier könnte Ihre Lösung stehen"?

    Hallo allerseits,
    ich steh grad mächtig auf dem Schlauch und benötige nen kleinen Schubser in die richtige Richtung.

    EDIT: genutzt wird VB in VisualStudio2010

    Ich habe folgendes 3-dimensionales Array:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Userdata(9, 27, 10) As String


    Was muss ich mit diesem (bereits gefüllten) Array anstellen, um es in Byte zu konvertieren? Vom Gefühl her würde ich sagen, es müssen (wie auch immer) vorher alle 3080 Felder (als einziger String) in eine Variable gepackt werden, welche dann wiederum in Byte konvertiert wird. Ist der Ansatz korrekt oder bin ich hier auf dem Holzweg?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. if Holzweg then
    2. MsgBox("Wie lässt sich das eleganter anstellen?")
    3. end if


    Hintergrund der Aktion ist die darauf folgende Verschlüsselung von Nutzerdaten, ohne diese auch nur für Sekundenbruchteile unverschlüsselt in einer Datei zu speichern (dieses Vorhaben funktioniert bereits, dabei wird allerdings der Dateiinhalt als FileStream direkt in Byte aufbereitet und bei der Verschlüsselung verarbeitet).

    Merci im Voraus und LG

    John

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(

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

    Hey,
    vielen Dank. Serialisierung ist scheinbar das benötigte Stichwort, hatte ich für die ursprüngliche Vorgehensweise auch schon im Code, allerdings noch ohne Übergabe an den CryptoStream.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'Ursprüngliche Variante
    2. Dim SaveProfileFile As New FileStream(ProfileFile, FileMode.Open)
    3. Dim formatter As New BinaryFormatter
    4. formatter.Serialize(SaveProfileFile, Userdata) 'Userdata ist mein String-Array
    5. SaveProfileFile.Close()
    6. 'Hier der Versuch der Umstellung auf MemoryStream
    7. Dim SaveProfileFile As New MemoryStream
    8. Dim formatter As New BinaryFormatter
    9. formatter.Serialize(SaveProfileFile, Userdata)
    10. 'Wie kann ich mir jetzt quick'n'dirty die serialisierten Daten anzeigen lassen (um am Output zu sehen, ob tatsächlich etwas passiert ist)?
    11. MsgBox(SaveProfileFile) 'funktioniert freilich nicht, da die Daten ja nicht als String, sondern (für mein Verständnis) Binär sein sollten


    EDIT: So, jetzt habe ich mir den Vorgängerpost nochmal durchgelesen und bin nun endgültig verwirrt. Meine (geplante) Vorgehensweise war:

    (1)Array -> (2)MemoryStream -> (3)CryptoStream -> (4)Datei

    Oder ist Schritt (2) für mein Vorhaben komplett überflüssig?

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(

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

    Guten Morgen @JohnDenver0815

    Die Idee über den Crypto- und Filestream funktioniert sehr gut.

    Wenn du noch keine Verschlüsselung hast dann nimm doch einfach die AES. Die hat sich bestens bewährt.
    Für Salt,Key und iv gibt es Rfc2898DeriveBytes

    Basis
    *****
    Erzeuge dir eine neue öffentliche Salt mit z.B. einem selber gemachten Generator mit mindestens der gleichen Länge wie das Passwort. Dein Passwort sollte aber schon min. 8 Zeichen lang sein.
    Für Key und iv nutze Rfc2898DeriveBytes. Dafür brauchst du dein pw und salt.

    Für das Encrypting
    **********************
    Erzeuge eine Using-AesCryptoServiceProvider-Instanz
    In die Instanzvariable kannst du dann Iv und key setzen
    Dann CreateEncryptor damit eine Transformation überhaupt möglich ist
    Nun eine Using-FileStream-Instanz
    nachher noch die Using-CryptoStream-Instanz
    und zu guter letzt die BinaryFormatter instanzieren
    Serialisieren

    Für das Decrypting
    **********************
    Erzeuge eine Using-AesCryptoServiceProvider-Instanz
    In die Instanzvariable kannst du dann Iv und key setzen
    Dann CreateDecryptor(!!!!!) damit eine Transformation überhaupt möglich ist
    Nun eine Using-FileStream-Instanz
    nachher noch die Using-CryptoStream-Instanz
    und zu guter letzt die BinaryFormatter instanzieren
    Deserialisieren

    Das wars

    Freundliche Grüsse

    exc-jdbi
    Momentan läuft es folgendermaßen ab:

    Bei Programmstart wird ein Passwort abgefragt, welches als SHA512-Hash in einer Variablen gespeichert wird (damit es nicht im Klartext im Speicher rumdümpelt).

    Für die eigentliche Verschlüsselung habe ich mir von hier den Code soweit angepasst, dass es (bisher) für meine Bedürfnisse reichte (hier wird zwar der PW-Hash erneut gehashed, aber da sehe ich jetzt persönlich keine Schwierigkeiten drin -> falls dem nicht so ist, dann bitte den Kommentar mit Erklärung zurück). Jetzt muss ich den CryptoStream nur noch dahingehend anpassen, dass er nicht auf eine Datei, sondern auf mein Array zurück greift. Dann sollte eigentlich alles funzen.

    Vielen Dank erstmal für die Hilfe/Tips. Wenn alles läuft gibts hier etwas Beispielcode sowie die obligatorischen "Hilfreich-Daumen".

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(
    Hatte gerade vor Kurzem was ähnliches. Jedoch mit 3D-Integer-Array. Sofern du dich trozdem für AES entscheidest. hier ne kleine Vorlage.
    Es gäbe noch die Möglichkeit über Jagged-Array. Sie liegt auch im Beispiel bei.

    Edit: Prüfe bei DecSerialize zuerst noch ob die Datei vorhanden ist mit If File.Exists(FileName) Then, da Filestream nur die Mode Open/Read besitzt.

    Freundiche Grüsse

    exc-jdbi
    Dateien
    • Module1.vb

      (9,63 kB, 88 mal heruntergeladen, zuletzt: )

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

    Moin allerseits,
    es war eine Weile ruhig um mich, was aber weniger daher rührt, dass die Zeit fehlt, sondern eher das Verständnis für die Dinge, die da passieren. Irgendwie krieg ich das selbst mit den Beispielen weder in den Kopf noch lauffähig ins Projekt. Ich bin, glaube ich, noch zu sehr QBasic-geschädigt und habe daher so meine Schwierigkeiten mit OOP.

    Ich möchte hier definitiv keinen C&P-Code, sondern das Ganze auch irgendwie verstehen, daher hier gleich noch eine Noob-Frage:

    Wie würdet ihr das Ergebnis nach dem Serialisieren eines 3D-String-Arrays bezeichnen? Ist das "nur" ein Objekt, ein Byte-Array oder doch irgendwas anderes?

    So langsam aber sicher stoße ich an meine Grenzen, was das Auffinden von (verständlichen) Erklärungen zu komplizierteren Themen angeht.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Enum CryptoAction
    2. 'Define the enumeration for CryptoAction.
    3. ActionEncrypt = 1
    4. ActionDecrypt = 2
    5. End Enum
    6. Sub EncryptOrDecryptFile(ByVal strInputFile As String, _
    7. ByVal strOutputFile As String, _
    8. ByVal bytKey() As Byte, _
    9. ByVal bytIV() As Byte, _
    10. ByVal Direction As CryptoAction)
    11. 'Setup file streams to handle input and output.
    12. fsInput = New System.IO.FileStream(strInputFile, FileMode.Open, _
    13. FileAccess.Read)
    14. fsOutput = New System.IO.FileStream(strOutputFile, _
    15. FileMode.OpenOrCreate, _
    16. FileAccess.Write)
    17. fsOutput.SetLength(0) 'make sure fsOutput is empty
    18. 'Declare variables for encrypt/decrypt process.
    19. Dim bytBuffer(4096) As Byte 'holds a block of bytes for processing
    20. Dim lngBytesProcessed As Long = 0 'running count of bytes processed
    21. Dim lngFileLength As Long = fsInput.Length 'the input file's length
    22. Dim intBytesInCurrentBlock As Integer 'current bytes being processed
    23. Dim csCryptoStream As CryptoStream
    24. 'Declare your CryptoServiceProvider.
    25. Dim cspRijndael As New System.Security.Cryptography.RijndaelManaged
    26. 'Determine if encryption or decryption and setup CryptoStream.
    27. Select Case Direction
    28. Case CryptoAction.ActionEncrypt
    29. csCryptoStream = New CryptoStream(fsOutput, _
    30. cspRijndael.CreateEncryptor(bytKey, bytIV), _
    31. CryptoStreamMode.Write)
    32. Case CryptoAction.ActionDecrypt
    33. csCryptoStream = New CryptoStream(fsOutput, _
    34. cspRijndael.CreateDecryptor(bytKey, bytIV), _
    35. CryptoStreamMode.Write)
    36. End Select
    37. 'Use While to loop until all of the file is processed.
    38. While lngBytesProcessed < lngFileLength
    39. 'Read file with the input filestream.
    40. intBytesInCurrentBlock = fsInput.Read(bytBuffer, 0, 4096)
    41. 'Write output file with the cryptostream.
    42. csCryptoStream.Write(bytBuffer, 0, intBytesInCurrentBlock)
    43. 'Update lngBytesProcessed
    44. lngBytesProcessed = lngBytesProcessed + _
    45. CLng(intBytesInCurrentBlock)
    46. End While
    47. 'Close FileStreams and CryptoStream.
    48. csCryptoStream.Close()
    49. fsInput.Close()
    50. fsOutput.Close()
    51. End Sub


    Das ist die vorhandene En-/DeCrypt-Routine, welche allerdings Dateien (Filestreams) ver- und entschlüsselt. Nun muss ich diese Routine (für mein Verständnis) in zwei einzelne Routinen (De- und Encrypt) splitten, da sich je nach Anwendung Source und Destination ändern -> Encryption(Input: Array | Output: Filestream) | Decryption(Input: Filestream | Output: Array). Und genau hier scheitert es wieder am Verständnis (siehe folgende Sub-Definitionen):

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub EncryptArrayToFilestream(ByVal strInputArray As Array, _
    2. ByVal strOutputFile As String, _
    3. ByVal bytKey() As Byte, _
    4. ByVal bytIV() As Byte)
    5. End Sub
    6. Sub DecryptFilestreamToArray(ByVal strInputFile As String, _
    7. ByVal strOutputArray As Array, _
    8. ByVal bytKey() As Byte, _
    9. ByVal bytIV() As Byte)
    10. End Sub


    Ich vermute, dass ich mit dem

    VB.NET-Quellcode

    1. ​As Array
    schon auf dem Holzweg bin.


    Nun ja, ich probiere es weiter, bis es klappt.

    MfG und schonmal ein schönes WE

    John

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(

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

    Ganz einfach ausgedruckt.

    Es handelt sich schon um eine Byte-Array in der Datei, die jedoch durch ihre konstellation eine gewisse Struktur besitzt (sequenzielle Darstellungsform gemäss Wikipädia).

    Wird die Datei (Byte-Array) nun in den Deserialisierungs-Datenstrom gelegt, wird daraus ein ganz bestimmtes Object gebildet. Und diese Object entspricht in der Umwandlung dem Object das ursprünglich Serialisiert wurde.

    siehe Wikipedia

    Zu deinem Code.
    So wie ich das jetzt auf die Schnelle erkennen kann ist die While-Schleife vollkommen überflüssig, da du den Filestream gepuffert hast, was übrigends auch nicht nötig ist. DotNet steckt auch grosse Datenmengen problemlos weg.

    Wenn ich dir einen Typ geben darf. Schau dir den Code, den ich geschrieben habe mal gründlich durch. Du musst ja nicht kopieren, sondern es soll dir lediglich das Vorgehens vermitteln.

    DotNet hat nicht einfach so die Using-Instanzierungen eingeführt, Sie erleichtern vieles und man muss sich nicht um die Rücksetzung der Instanzen kümmern.

    Freundliche Grüsse

    exc-jdbi

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

    Hab kurz Zeit gefunden.

    Anscheinend wilst du mit deiner Funktion nicht Serialisieren sondern nur Crypten, und zwar in beiden Richtungen, also Encrypten wie auch Decrypten.

    VB.NET-Quellcode

    1. Public Sub EncryptOrDecryptFile(ByRef obj As String(,,), _
    2. ByVal sFileName As String, _
    3. ByVal bytKey() As Byte, _
    4. ByVal bytIV() As Byte, _
    5. ByVal Direction As CryptoAction)



    Das Vorgehen ist sehr ähnlich.
    *************************************

    Using-RijndaelManaged-Instanz erzeugen
    In die Instanzvariable kannst du dann Iv und key setzen
    Using-FileStream-Instanz: Am besten eine Funktion machen, die gleich den richtig gsetzten Filestream übergibt. Also irgendwie

    VB.NET-Quellcode

    1. GetFileStream(sFileName, Direction) As FileStream

    Using-CryptoStream-Instanz und auch hier bei Mode irgend ne Funktion wie

    VB.NET-Quellcode

    1. GetCSMode(Direction) As CryptoStreamMode

    So hast du Ordnung, und für das sind Funktionen hier.
    Jetzt eine klare Trennung von ActionEncrypt/ActionDecrypt z.B. mit If-Then-ElseIf

    Encrypt
    Ich empfehle dir die sFileName-Datei unbedingt vorher zu löschen. Manchmal können genau deswegen Probleme entstehen.
    Eine 3D-Variable ist kubisch das heisst die Size ist 3-Wurzel(3D-Variable)
    Um an die Strings ran zu kommen musst du 3 Forschleifen machen. Mach dir dann am besten eine Byte-Array und lass dir den string in byte umwandeln. Setzen noch ein Erkennungsmerkmal am Schluss des Strings wie z.B. VBCrLf, damit die Strings nachher beim Decrypten gesplittet werden können.
    Jetzt kann mit der Cryptostream-Variable (write) die Byte-Array in den Stream geschrieben werden.
    Wenn das alles fertig ist unbedingt den Cryptostream Flushen (FlushFinalBlock!!)

    Decrypt

    Für das Zurücklesen wird noch ein Reader benötig, jedoch einer der zum Stream passt, also z.B. ein Streamreader
    Using-Streamreader-Instanz
    Jag die ganze Datei in den Stringbuilder
    Splite den Stringbuilder in eine Stringarray (Option: RemoveEmptyEntries)
    Nun solltest du die Sizegrösse haben also wieder 3-Wurzel(Stringarray)
    Eine 3d-String neu instanzieren, also obj=new (..,..,..){}
    Nun die StringArray in die 3D-Variable einspielen (z.B. mit 3 For-schleifen)

    Zeilenweises einlesen beim Decrypt mit den Streamreader ist auch möglich, dann vorher beim Encrypten die entsprechenden Array-Infos z.B. in der ersten Zeile eingeben. Z.B.

    VB.NET-Quellcode

    1. 'In erste Zeile beim Encrypt die ArraySize's schreiben
    2. b = Encoding.UTF8.GetBytes(obj.GetLength(0).ToString & ",," & _
    3. obj.GetLength(1).ToString & ",," & _
    4. obj.GetLength(2).ToString & vbCrLf)
    5. cs.Write(b, 0, b.Length)


    Fertig

    Freundliche Grüsse

    exc-jdbi

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

    [Ironie]Ach herrje, hätt ich doch nur zeitiger hier reingeschaut, dann hätte ich mir jede Menge Hirnschmalz, Ärger und Rumprobiererei erspart.[/Ironie] Stattdessen bin ich mittlerweile selbst auf eine für mich plausibel erscheinende Lösung gekommen. Es wäre schön, wenn hier mal jemand quer lesen könnte, ob das vernünftig oder Nonsens ist (obwohl das Ergebnis recht kryptisch aussieht und auch reversibel ist).

    Der bisher verwendete Code (woher der stammt ist aus diesem Post ersichtlich) zum Generieren des Schlüssels als auch des IV ist im Programm verblieben:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Security.Cryptography
    3. Imports System.Runtime.Serialization.Formatters.Binary
    4. Module EncryptionClass_AES_Rijndael
    5. '*************************
    6. '** Create A Key
    7. '*************************
    8. Function CreateKey(ByVal strPassword As String) As Byte()
    9. 'Convert strPassword to an array and store in chrData.
    10. Dim chrData() As Char = strPassword.ToCharArray
    11. 'Use intLength to get strPassword size.
    12. Dim intLength As Integer = chrData.GetUpperBound(0)
    13. 'Declare bytDataToHash and make it the same size as chrData.
    14. Dim bytDataToHash(intLength) As Byte
    15. 'Use For Next to convert and store chrData into bytDataToHash.
    16. For i As Integer = 0 To chrData.GetUpperBound(0)
    17. bytDataToHash(i) = CByte(Asc(chrData(i)))
    18. Next
    19. 'Declare what hash to use.
    20. Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    21. 'Declare bytResult, Hash bytDataToHash and store it in bytResult.
    22. Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    23. 'Declare bytKey(31). It will hold 256 bits.
    24. Dim bytKey(31) As Byte
    25. 'Use For Next to put a specific size (256 bits) of
    26. 'bytResult into bytKey. The 0 To 31 will put the first 256 bits
    27. 'of 512 bits into bytKey.
    28. For i As Integer = 0 To 31
    29. bytKey(i) = bytResult(i)
    30. Next
    31. Return bytKey 'Return the key.
    32. End Function
    33. '*************************
    34. '** Create An IV
    35. '*************************
    36. Function CreateIV(ByVal strPassword As String) As Byte()
    37. 'Convert strPassword to an array and store in chrData.
    38. Dim chrData() As Char = strPassword.ToCharArray
    39. 'Use intLength to get strPassword size.
    40. Dim intLength As Integer = chrData.GetUpperBound(0)
    41. 'Declare bytDataToHash and make it the same size as chrData.
    42. Dim bytDataToHash(intLength) As Byte
    43. 'Use For Next to convert and store chrData into bytDataToHash.
    44. For i As Integer = 0 To chrData.GetUpperBound(0)
    45. bytDataToHash(i) = CByte(Asc(chrData(i)))
    46. Next
    47. 'Declare what hash to use.
    48. Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    49. 'Declare bytResult, Hash bytDataToHash and store it in bytResult.
    50. Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    51. 'Declare bytIV(15). It will hold 128 bits.
    52. Dim bytIV(15) As Byte
    53. 'Use For Next to put a specific size (128 bits) of bytResult into bytIV.
    54. 'The 0 To 30 for bytKey used the first 256 bits of the hashed password.
    55. 'The 32 To 47 will put the next 128 bits into bytIV.
    56. For i As Integer = 32 To 47
    57. bytIV(i - 32) = bytResult(i)
    58. Next
    59. Return bytIV 'Return the IV.
    60. End Function


    Die Verschlüsselungsfunktion (auf Basis des Codes von @exc-jdbi):
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Function EncSerialize(Of T)(ByVal FileName As String, ByVal obj As T) As Boolean
    2. Dim bytKey As Byte()
    3. Dim bytIV As Byte()
    4. bytKey = CreateKey("Passwort")
    5. bytIV = CreateIV("Passwort")
    6. Using cspRijndael As New System.Security.Cryptography.RijndaelManaged
    7. Using ce As ICryptoTransform = cspRijndael.CreateEncryptor(bytKey, bytIV)
    8. Using fs = New FileStream(FileName, FileMode.Create, FileAccess.Write)
    9. Using cs = New CryptoStream(fs, ce, CryptoStreamMode.Write)
    10. Dim bf As New BinaryFormatter()
    11. bf.Serialize(cs, obj)
    12. Return True
    13. End Using
    14. End Using
    15. End Using
    16. End Using
    17. Return False
    18. End Function

    Die Entschlüsselungsfunktion (ebenfalls auf Basis des Codes von @exc-jdbi):
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Function DecSerialize(Of T)(ByVal FileName As String) As T
    2. Dim bytKey As Byte()
    3. Dim bytIV As Byte()
    4. bytKey = CreateKey("Passwort")
    5. bytIV = CreateIV("Passwort")
    6. Using cspRijndael As New System.Security.Cryptography.RijndaelManaged
    7. Using ce As ICryptoTransform = cspRijndael.CreateDecryptor(bytKey, bytIV)
    8. Using fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
    9. Using cs = New CryptoStream(fs, ce, CryptoStreamMode.Read)
    10. Dim bf As New BinaryFormatter()
    11. Return CType(bf.Deserialize(cs), T)
    12. End Using
    13. End Using
    14. End Using
    15. End Using
    16. Return Nothing
    17. End Function


    Der eigentliche Aufruf der Funktionen passiert dann folgendermaßen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Sub Load_Filecontent_to_MeinArray()
    2. MeinArray = DecSerialize(Of String(,,))("Mein Dateipfad/name") 'in diesem Fall ein 3D-Array, daher auch (,,)
    3. End Sub
    4. Sub Save_MeinArray_to_Filecontent()
    5. EncSerialize(Of String(,,))("Mein Dateipfad/name", MeinArray)
    6. End Sub


    Auf alle Fälle ein dickes Dankeschön für die Gedankenanstöße, Quelltextauszüge sowie den ein oder anderen Aha-Effekt (ich erzähl euch lieber nicht, dass ich sowas wie #Region schon lange gesucht habe X/ ). Die Hilfreich-Marker werden gleich verteilt und hier kann dann auch (sofern man den Code für tauglich befunden hat) zu.

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „JohnDenver0815“ ()

    Hallo @JohnDenver0815

    Ich hab den Code kurz überflogen. Das sollte funktionieren. :thumbup:

    Nur was mir gerade aufgefallen ist. Man könnte noch ein paar Kleinigkeiten optimieren:

    Importiere zuoberst den Namespace Imports System.Text
    Mit Getbytes kann man einen String in eine Byte-Array umwandeln
    Mit Array.Copy sparrt man sich viel Code

    VB.NET-Quellcode

    1. 'Im 1. Spoiler Zeile 17 - 35
    2. Dim bytDataToHash() As Byte
    3. bytDataToHash = Encoding.utf8.GetBytes(strPassword)
    4. 'Zeile 47 - 59
    5. Dim bytKey(31) As Byte
    6. Array.Copy(bytResult, bytKey, 32)
    7. 'Zeile 73 - 91
    8. Dim bytDataToHash() As Byte
    9. bytDataToHash = Encoding.utf8.GetBytes(strPassword)
    10. 'Zeile 103 - 115
    11. Dim bytIV(15) As Byte
    12. Array.Copy(bytResult, 32, bytIV, 0, 16)


    SHA512Managed

    VB.NET-Quellcode

    1. 'Nutze auch bei SHA512Managed Using
    2. Using SHA512 As New SHA512Managed
    3. 'Code
    4. End Using


    In der Funktion DecSerialize als allererstes. Prüfe zuerst ob die Datei vorhanden ist. (fs ==> FileMode.Open, FileAccess.Read)

    VB.NET-Quellcode

    1. If File.Exists("DeinPfadZurDatei") Then


    Wenn du magst in der Funktion EncSerialize zuerst die Datei löschen. Ist eine reine Vorsichtsmassnahme, da in den Filestream-Instanzierungen gerne die FileMode.CreateOpen.Mode genommen wird. So können keine unvorhergesehene Sachen entstehen, wie z.B. dass das neuen an den Schluss der Datei geschrieben wird.

    VB.NET-Quellcode

    1. If File.Exists("DeinPfadZurDatei") Then file.delete("DeinPfadZurDatei")


    CreateKey("Passwort") / CreateIV("Passwort")
    sind sehr gefährlich. Ich geh davon aus, dass man langsam weiss, dass keine Passwörter (schon gar nicht im Klartext) im Code vorhanden sein dürfen.


    Freundliche Grüsse

    exc-jdbi

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

    CreateKey("Passwort") / CreateIV("Passwort")

    sind sehr gefährlich. Ich geh davon aus, dass man langsam weiss, dass
    keine Passwörter (schon gar nicht im Klartext) im Code vorhanden sein
    dürfen.


    Keine Angst, das war hier lediglich zur Veranschaulichung, was genau da rein muss. In meinem Fall wird zur Laufzeit ein PW angefordert, von welchem der Hash in meiner Variablen gespeichert wird. Diese Variable steht bei mir anstelle von "Passwort".

    Den Rest schau ich mir heut Abend nochmal an, wenn ich meinen Editor wieder zur Hand habe.

    LG
    John

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(
    Dein obiger Code hat übrigends ein grosses Problem. So wie es jetzt gestaltet ist, hat man immer den gleichen IV und immer en gleichen Key. Das kann man problemlos feststellen. Setze auf Zeile 61 und Zeile 117 in deinem obigen Code einen Breakpoint. Egal wie du es handhabst, Key und Iv sind immer gleich, ausser du änderst dein Password.

    Dazu dieser Artikel
    Initialisierungsvektor

    Ich kann dir nur empfehlen eine Lösung mit salt zu erstellen. Es gibt dazu die Funktion Rfc2898DeriveBytes. Wenn Rfc2898DeriveBytes nicht in frage komm, dann müsste man auf was anders ausweichen. Rfc2898DeriveBytes ist von dem her auch schon wieder veraltet. und wenn ich mich recht besinne, basiert es auf Sha1.

    Meiner Meinung nach sollte salt sowieso immer wieder neu generiert werden. Also nach jedem Encrypt + Decrypt Vorgang wieder ein neues salt, dass irgendwo in eine Datei gespeichert werden kann. Das finde ich so sicherer.
    Ausser vielleicht man besitzt eine Vorrichtung, in dem sichergestellt wird, dass Iv + Key sich immer komplett ändern, wen ein solcher Vorgang (Encrypt +Decrypt) gestartet wird. Aber auch dann, wäre ich lieber auf der sicheren Seite, und generiere mir schnell ein neues salt.

    Freundliche Grüsse

    exc-jdbi
    Eines vorweg: mein PW besteht selbstverständlich nicht nur aus der reinen Nutzereingabe, sondern wird vor dem Hashen noch mit fix im Code hinterlegten Zahlen/Buchstaben sowie diversen String-Spielereien mit sich selbst (z.B. StrReverse) angereichert.
    Logisch, hier fehlt dennoch die Dynamik.

    Der Gedankengang an sich mit dem salt ist nicht verkehrt, hier habe ich mir auch schon so meine Gedanken gemacht. Ich bin zu dem Schluss gekommen, dass ich das salt nicht irgendwo in einer extra Datei unterbringe, da damit folgende Layer-8-Fehlerquelle entsteht: kommt die Datei aus welchen Gründen auch immer abhanden, ist es unmöglich, die Nutzdaten (selbst mit richtigem Passwort) zu entschlüsseln. Da ein salt ja durchaus öffentlich einsehbar sein kann, könnte ich das theoretisch mit einer fixen Länge auch vor den verschlüsselten Nutzdaten in meiner Datei hinterlegen.

    Ein weiterer Gedanke meinerseits war, den Dateinamen ebenfalls ins PW mit einfließen zu lassen. Somit wäre eine gewisse Dynamik gegeben und hätte noch den "positiven" Nebeneffekt, dass Datenpfuschern an dieser Stelle das Handwerk gelegt wird. Klar renne ich damit zwangsläufig früher oder später in eine Exception, aber die kann man ja behandeln (derzeit werden bei einem Entschlüsselungsfehler sämtliche Nutzdatendokumente als Backup weggezipped und eine komplett blanke Maske angezeigt). Als einziges Problem an der Sache sehe ich momentan nur diverse Dateinamenkonventionen, d.h. ich müsste die Dateinamen vor der "Aufnahme ins PW" einheitlich (im Speicher) konvertieren.


    Und für alle, die sich jetzt die Frage stellen, was ich hier überhaupt versuche auf die Beine zu stellen:
    Spoiler anzeigen
    Ich war es leid, mir auf Arbeit tausende von Verknüpfungen mit abertausenden Userdaten zu merken bzw. im Browser (mittlerweile Dank Firmenrichtlinie geblockt) oder im Windows-Tresor zu hinterlegen. Ebenso das Schlüsselbund bei Apple, aber das ist eine andere Geschichte, die WINE-Anpassung ist noch in weiter Ferne. Nun gibt es Kollegen, die sich den ganzen Kladderadatsch in nem Excel-File hinterlegt haben (StrReverse(SafetyFirst)) sowie Leute, die sich das alles in ein kleines schlaues Buch schreiben. Da ist allerdings wiederum schwierig mit Copy&Paste. Also musste eine Lösung her. Mittlerweile ist der Link-Master soweit, dass es pro Profil (also pro Datei) 10 Slots á 28 Buttons gibt, welche mit allem Möglichen verlinkt werden können (z.B. Dateien, Ordner Programme, Webseiten etc.). Sogar Programmaufrufe mit Parameterangaben sind implementiert (z.B. "excel.exe meinsharepoint.de/datei.xlsx"). Zu guter Letzt lassen sich die Buttons noch farblich anpassen, da 28 graue Buttons auf einer Form auch recht unübersichtlich sein können. Nicht zu vergessen ist die Übergabe von je Link hinterlegbarem User/PW sowie die Autostartfunktion der gewünschten Links (getreu dem Motto: morgens auf Arbeit den Rechner hochfahren, ein Mausklick und dann ab zum Kaffeeautomaten. Bei Rückkehr sind alle Tools gestartet, die man so braucht und es kann sofort los gehen). Jetzt mag es sicher hier und da jemanden geben, der meint, das könne Windows auch per Autostart. Dem stimme ich zu, allerdings mit mehreren Gegenargumenten.
    • 1. würde der Systemstart unnötig aufgebläht werden
    • 2. startet der Scheduler (für mein Empfinden) alles auf einmal, der Link-Master alles nacheinander in fest definierbaren Abständen
    • 3. müssten sämtliche Userdaten wieder im Windows-Tresor, im Browser und sonstwo hinterlegt werden (kann man den ganzen "Vereinen" trauen?)
    • 4. ist der Scheduler auf einen bestimmten Rechner limitiert, während der Link-Master komplett portable designed ist -> Vorteil: alle wichtigen Links & Userdaten verschlüsselt auf einem Stick in der Hosentasche und somit universell an jedem (Windows-)Rechner einsetzbar, gerade auch in Kombination mit weiteren Portable-Lösungen wie z.B. Firefox oder SecureCRT
    • 5. habe ich ein per Autostart gestartetes Programm geschlossen, muss ich wieder irgendeinen Link auf der Platte raus kramen -> beim Link-Master bin ich nur einen Klick vom erneuten Anzeigen entfernt
    • 6. weiß ich selbst, was ich hier zurecht gecoded habe und bin mir sicher, dass meine Daten nicht ohne mein Wissen woanders landen
    • 7. Vor- als auch Nachteil (je nach Sichtweise): ich habe keinerlei Hintertür eingebaut, d.h. es ist mir nicht möglich, ein verlegtes Master-PW auch nur ansatzweise zurückzuholen. Ergo: wenn der User nicht aufpasst, dann sind seine Nutzerdaten auf ewig im Nirvana. Entweder man hat sie noch im Kopf, irgendwo woanders notiert oder kriegt es irgendwie gebacken, sich sein Master-PW zu merken.
    • Amen :D




    Um noch mal kurz zum Kern zu kommen, es wird selbstverständlich nicht in einer Tour ver-/entschlüsselt. Entschlüsselt wird nur beim Programmstart/Profilwechsel, verschlüsselt nur beim Programmende/Profilwechsel. Alles, was dazwischen passiert, läuft ohne Dateiaktionen komplett im Speicher ab.

    EDIT: Die Codeoptimierungen habe ich wie oben vorgeschlagen getestet und übernommen. Funktioniert perfekt :thumbup: Die Prüfung, ob die Datei existiert, erfolgt bereits an anderer Stelle im Code. Falls die zwischenzeitlich weggekommen sein sollte wird sie neu erstellt.

    "Ich bin schneller über Port 22 in Wladiwostok als du mit 'ner 24er Nuss vom Späti zurück."
    ?( ?( ?(

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „JohnDenver0815“ ()