Seite 1 von 1

MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 14:18
von Sauer-RAM
Hi, ich muss nun für die Schule einen Chat schreiben. Den will ich natürlich auch mit 255-Bit AES verschlüsseln.
Der folgende Code funktioniert die ersten paar Male, dann kommt jedes mal ein Speicherzugriffsfehler. Kann mir jemand sagen warum? Ich kenne mich leider mit den Speichern nicht so gut aus.
P.S. Ich hab den Code leier schon durch meine Fixversuche ziemlich verhunzt.

Code: Alles auswählen

Procedure.s EncryptString(String.s,Schluessel.s)
  
  *Schluessel = ReAllocateMemory(*Schluessel,Len(Schluessel.s) + 1)
  *Initiierungsvektor = ReAllocateMemory(*Initiierungsvektor,32)
  *CryptedString = ReAllocateMemory(*CryptedString,Len(String) + 1)
  
  PokeS(*Schluessel,Schluessel,-1,#PB_Ascii)
                                                                   ;*** Schlüssellänge anpassen ***
  If Len(Schluessel) + 1 <> 32
    Schluessel.s = MD5Fingerprint(*Schluessel,MemorySize(*Schluessel))            ;Wenn die Schlüssellänge ungleich 128 bit ist, wird der Schlüssel
    PokeS(*Schluessel,Schluessel.s,-1,#PB_Ascii)                                                               ;durch den MD5-Hashgenerator "gejagt" um ihn auf eine Länge von
                                                                   ;128 bit zu bringen (MD5-Hashes sind 128 bit groß)
  EndIf
                                                                   ;*** Initiierungsvektor erstellen ***
  If OpenCryptRandom() <> 0 And CryptRandomData(*Initiierungsvektor,32) <> 0 ;Öffnet den kryptografischen Zufallszahlengenerator
                                                                     
  Else                       
    ProcedureReturn ""  
  EndIf
  
  ;If MemorySize(*Initiierungsvektor) = 32                          ;Testet ob alles seine Richtigkeit hat
  ;Else
  ;  ProcedureReturn ""                                            ;... und bricht ab wenn etwas nicht stimmt
  ;EndIf
  CloseCryptRandom()                                                ;Schließt den kryptografischen Zufallszahlengenerato
  
  
  
  *CryptedString = AllocateMemory(Len(String)+1)
  If AESEncoder(@String,*CryptedString,Len(String),*Schluessel,256,*Initiierungsvektor)
  Else
    ProcedureReturn ""
  EndIf
  ;FreeMemory(*Schluessel)
  ;FreeMemory(*Initiierungsvektor)
  ProcedureReturn PeekS(*CryptedString)  
EndProcedure

Procedure EncryptData(*Daten,Schluessel.s)
  
  *Schluessel = AllocateMemory(Len(Schluessel))
  *Initiierungsvektor = AllocateMemory(32)
  
  PokeS(*Schluessel,Schluessel)
                                                                   ;*** Schlüssellänge anpassen ***
  If StringByteLength(Schluessel) <> 32
    MD5Fingerprint(*Schluessel,MemorySize(*Schluessel))            ;Wenn die Schlüssellänge ungleich 128 bit ist, wird der Schlüssel
                                                                   ;durch den MD5-Hashgenerator "gejagt" um ihn auf eine Länge von
                                                                   ;128 bit zu bringen (MD5-Hashes sind 128 bit groß)
  EndIf
                                                                   ;*** Initiierungsvektor erstellen ***
  If OpenCryptRandom() <> 0 And CryptRandomData(*Initiierungsvektor,32) <> 0 ;Öffnet den kryptografischen Zufallszahlengenerator
                                                                     
  Else                       
  EndIf
  
  If MemorySize(*Initiierungsvektor) = 32                          ;Testet ob alles seine Richtigkeit hat
  Else
    ProcedureReturn  0                                            ;... und bricht ab wenn etwas nicht stimmt
  EndIf
  
  
  
  *CryptedData = AllocateMemory(MemorySize(*Daten))
  If AESEncoder(*Daten,*CryptedData,MemorySize(Daten),*Schluessel,256,*Initiierungsvektor)
  Else
    ProcedureReturn 0
  EndIf
  
  ProcedureReturn *CryptedData  
EndProcedure

For i = 17 To 500
  For u = 17 To 50
    String.s = ""
    Schluessel.s = ""
    X = 0
    Repeat: String.s = String.s + Chr(Random(100) + 34): X = X + 1 :Until x = i
    X = 0 
    Repeat: Schluessel.s = Schluessel.s + Chr(Random(100) + 34): X = X + 1 :Until x = u
    Enc.s = EncryptString(String.s,Schluessel.s)
    Debug "Enc: " + Str(Len(Enc)) + "String: " + Str(Len(String)) + "Schlüssel: " + Str(Len(Schluessel)) + Enc
  Next
Next
Ich hoffe hier kann mir jemand helfen. Danke schonmal im Vorraus ^^

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 14:47
von Kiffi
hier hast Du schon mal einen Fehler:

Code: Alles auswählen

[...] MemorySize(Daten) [...]
(mit EnableExplicit wäre das nicht passiert ;-))

Des weiteren ist mir aufgefallen, dass der IMA immer bei i=24 und u=18 kommt.

Den Rest müssen die Crypto-Experten rausfinden.

Grüße ... Kiffi

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 15:02
von STARGÅTE
In dem Code sind mehr fehler:

oben reservierst du den Speicher: *Schluessel = ReAllocateMemory(*Schluessel,Len(Schluessel.s) + 1)

schreibst aber unten den MD5 (wenn Schluessel < 32) trotzdem in den Speicher *Schluessel obwohl dieser zu klein ist!!
Dort wäre also auch ein reallocate nötig mit 32+1 Byte

Dann ist bei AES wichtig, dass der zu verschlüsselde Teil (also @String) mindestens 128Bit (16Byte) groß ist, da der algo mit 16-Byte-Blöcken arbeitet. Auch das prüfst du nicht.

Desweiteren finde ich es seltsam, dass du zwar 256Bit bei AES angibst, dein Schlüssel aber nur 128Bit (von MD5) hat.

ProcedureReturn PeekS(*CryptedString)
ist natürlich genauso quatsch, da *CryptedString kein String ist, sondern Binärdaten mit NUL-Zeichen.

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 15:05
von Sauer-RAM
Danke...
Öhm, ja ich meine nur die erste Prozedur. Die Zweite habe ich einfach kopiert und wollte sie auf Dateien umschreiben. Dann hab ich gemerkt, dass die erste nicht mal läuft und die Arbeit an der zweiten unterbrochen. :oops: Hab ich vergessen zu erwähnen, Sorry...
Ich denke ich lass das nun weg, und übermittle das Passwort in klartext... scheinbare Sicherheit ist besser als garkeine Sicherheit.

P.S. bei mir kommt der Fehler immer bei 24 Bytes Stringgröße und 17 Bytes O_o

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 15:13
von Sauer-RAM
Stargate: Danke, da lag wohl der Fehler
Zu der überprüfung: Ich will damit ja netzwerkverkehr verschlüsseln. Mit absender und empfänger. Also allein schon der Header ist schon größer als 16-Bit (Zwei Zeichen...), das Problem kommt also nie auf.

Zudem will AES bei 256 Bit, einen 32 Byte großen Schlüssel. MD5 gibt (so wie ich das gesehen habe) 32 Zeichen in String zurück á 1 Byte pro Zeichen.

Aber vielen vielen Dank Stargate. Der Code läuft jetzt, der Buffer war einfach zu klein...

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 15:37
von NicTheQuick
Sauer-RAM hat geschrieben:Zudem will AES bei 256 Bit, einen 32 Byte großen Schlüssel. MD5 gibt (so wie ich das gesehen habe) 32 Zeichen in String zurück á 1 Byte pro Zeichen.
Der MD5-Fingerprint hat nur deswegen 32 Zeichen, damit man die 128 Bit = 16 Bytes in lesbarer Form hat. Deswegen kommen im MD5-Fingerprint ja auch nur die Zeichen 0-9 und a-f vor. Eigentlich musst du den 32-Zeichen-String des MD5-Fingerprints noch in binäre 16 Byte umwandeln, damit es Sinn macht.

Davon abgesehen macht es keinen Sinn für jede Verschlüsselung einen anderen Initialisierungsvektor zu nehmen. Wenn du dir den nicht merkst, kannst du das ganze ja nicht mehr entschlüsseln. Normalerweise werden solche Initialisierungsvektoren zuerst zwischen den beiden Clienten ausgetauscht, also ein Schlüsselaustausch wie z.B. mit Diffie-Hellmann.

Man kann den Initialisierungsvektor allerdings auch fest einprogrammieren oder sogar veröffentlichen. Dann muss aber das Passwort entsprechend sicher sein, also z.B. ebenfalls mit Diffie-Hellmann ausgetauscht werden oder ähnliches. Weiterhin ist MD5 mittlerweile überholt. Da sollte man eher einen SHA1-Hash nehmen oder noch bessere kombinierte Verfahren.

Nochmal wegen deiner Funktion da. Reservier doch gleich für den Schlüssel immer 32 Bytes und hashe das Passwort immer. Dann brauchst du nicht so komplizierte Bedingungen dazwischen bauen. Alles andere hat STARGÅTE schon gesagt.

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 15:46
von Sauer-RAM
Ok Das mit dem Initialisierungsvektor hab ich auch gerade gemerkt... Ich denke ich nehm einen festen. Zudem hashe ich jetzt auch immer. Ich schicke euch den Code wenn er fertig ist zur freien Verfügung.
@Nic Wie meinst du das? Im Speicherbereich steht doch der String als Binär oder muss ich diesen wirklich über Bin(ASC()) noch umwandeln?

Danke für die Hilfe übrigens.

Re: MD5-Error (Ungültiger Speicherzugriff)

Verfasst: 06.05.2013 16:10
von STARGÅTE
MD5() gibt in PureBasic die Hexadezimalform eines 128Bit (16Byte) Binären Hashs zurück.
Das heißt immer zwei Zeichen (00 bis FF) bilden in wirklichkeit ein "echtes" Byte.
Du kannst natürlich auch die 32Byte der Hexadizimalform des MD5 nutzen, hast dadurch aber nicht mehr "Informationen" als in den echten 16Byte der Originalform.

Wenn du es umwandeln willst, dann zB PokeA(*Buffer+Position, Val("$"+Mid(HexHash, Position*2+1, 2)))
Für Position von 0 bis 15, dann aber bei AES den 128-Mode nutzen.