MD5-Error (Ungültiger Speicherzugriff)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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 ^^
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
Kiffi
Beiträge: 10725
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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
a²+b²=mc²
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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...
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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.
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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.
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: MD5-Error (Ungültiger Speicherzugriff)

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten