Vernam Verschlüsselung mittels XOR'en oder OTP(one time pad)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Blitzer
Beiträge: 79
Registriert: 26.09.2004 14:33
Wohnort: Lower Saxony

Vernam Verschlüsselung mittels XOR'en oder OTP(one time pad)

Beitrag von Blitzer »

Moin,

ich suche eine schnelle Möglichkeit, um Dateien mit XOR zu verschlüsseln.

Unter C++ (mit MinGW) habe ich eine sehr schnelle Kommandozeilen-Lösung. Unter PB funktioniert meine Umsetzung leider noch nicht.

Zum Verständnis:
1) Die Dokumentendatei und der Schlüssel sind gleich lang.
2) Das Dokument soll mit der Schlüsseldatei xor'd werden.


Beispiel-Code...

Code: Alles auswählen

ReadFile(0,"Dokument):dokumentsize=Lof(0):CloseFile(0)
ReadFile(1,"schluessel"):keysize=Lof(1):CloseFile(1) 
; Ab in den Speicher...
If ReadFile(1,"Dokument")                                ; Dokument-Datei öffnen
  *dokument2=AllocateMemory(dokumentsize)    ; Speicher reservieren (für Länge des Dokumentes)
    ReadData(1,*dokument2,dokumentsize)         ; Einlesen der Zeichen in den Speicher
  CloseFile(1)
EndIf
If ReadFile(2,"schluessel")                               ; Keydatei öffnen
  *schluessel2=AllocateMemory(dokumentsize)   ; Speicher reservieren (für Länge der Datendatei)
    ReadData(2,*schluessel2,dokumentsize)        ; Einlesen der Zeichen in den Speicher
  CloseFile(2)
EndIf

Nun sollen beide Speicher xor'd ... und abgespeichert werden...

Code: Alles auswählen

If  CreateFile(3,"Datei-xor")                           
  WriteData(3,*schluessel2,dokumentsize)         ; Arbeitsspeicher in Datei speichern
  CloseFile(3)                                               
EndIf
Kennt jemand eine schnelle Lese/Schreib Routine? Ich habe verschiedene Ansätze hier aus dem Forum ausprobiert, komme aber zu keinem brauchbaren Ergebnis.

Vielen Dank
Blitzer
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Vernam Verschlüsselung mittels XOR'en oder OTP(one time

Beitrag von NicTheQuick »

Ich würde es so machen.

Code: Alles auswählen

Procedure xorFiles(input.s, output.s, key.s)
	Protected hInput.i = ReadFile(#PB_Any, input)
	Protected hOutput.i = CreateFile(#PB_Any, output)
	Protected hKey.i = ReadFile(#PB_Any, key)
	
	Protected sizeInput.i = Lof(hInput)
	
	If sizeInput <> Lof(hKey)
		Debug "Eingabe- und Schlüsseldatei haben nicht die gleiche Größe."
		ProcedureReturn #False
	EndIf
	
	Protected *memInput.Integer = AllocateMemory(sizeInput)
	Protected *memOutput = *memInput
	If Not *memInput
		Debug "Nicht genug Speicher um die Eingabedatei zu öffnen."
		ProcedureReturn #False
	EndIf
	Protected *memKey.Integer = AllocateMemory(sizeInput)
	If Not *memKey
		Debug "Nicht genug Speicher um die Schlüsseldatei zu öffnen."
		ProcedureReturn #False
	EndIf
	
	ReadData(hInput, *memInput, sizeInput)
	ReadData(Hkey, *memKey, sizeInput)
	
	Protected i.i = 0
	; Erst mal mit Integern ver/entschlüsseln
	While i < sizeInput - SizeOf(Integer)
		*memInput\i ! *memKey\i
		*memInput + SizeOf(Integer)
		*memKey + SizeOf(Integer)
		i + SizeOf(Integer)
	Wend
	; Dann die restlichen 0-7 Bytes als Ascii verarbeiten
	While i < sizeInput
		PokeA(*memInput, PeekA(*memInput) ! PeekA(*memKey))
		*memKey + 1
		*memInput + 1
		i + 1
	Wend
	
	WriteData(hOutput, *memOutput, sizeInput)
	CloseFile(hInput)
	CloseFile(hOutput)
	CloseFile(hKey)
	
	ProcedureReturn #True
EndProcedure

xorFiles("/tmp/input.txt", "/tmp/output.txt", "/tmp/key.txt")
xorFiles("/tmp/output.txt", "/tmp/input2.txt", "/tmp/key.txt")
Bild
Blitzer
Beiträge: 79
Registriert: 26.09.2004 14:33
Wohnort: Lower Saxony

Re: Vernam Verschlüsselung mittels XOR'en oder OTP(one time

Beitrag von Blitzer »

@NicTheQuick
1024 mal :mrgreen:
Genau so so ist es für mich ok.

Bei meinem C++ Code kann der Schlüssel in der Länge größer oder kleiner als das Dokument sein. Bei kleinerem Schlüssel fängt es halt wieder von vorne an zu zählen.

Da ich ein PB-Cut-Programm habe, dass einen längeren Schlüssel passend abschneidet (so als wenn man ein Ende von einer Wurst abschneidet), belasse ich es erst einmal bei dieser Lösung - prima Job...

Blitzer
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Vernam Verschlüsselung mittels XOR'en oder OTP(one time

Beitrag von NicTheQuick »

Ersetze den folgenden Code

Code: Alles auswählen

   If sizeInput <> Lof(hKey)
      Debug "Eingabe- und Schlüsseldatei haben nicht die gleiche Größe."
      ProcedureReturn #False
   EndIf
einfach durch diesen

Code: Alles auswählen

	If sizeInput > Lof(hKey)
		Debug "Schlüsseldatei ist kleiner als die Eingabedatei."
		ProcedureReturn #False
	EndIf
Dann geht es auch, wenn die Schlüsseldatei größer als die Eingabedatei ist. Nur wenn sie kleiner ist, müsste man noch einiges umbauen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Vernam Verschlüsselung mittels XOR'en oder OTP(one time

Beitrag von NicTheQuick »

Ich kann mich erinnern, dass ich das hier schon mal programmiert habe. Aber so, dass es auch mit sehr großen Dateien funktioniert, die nicht in den Arbeitsspeicher passen. Und Schlüssel, die kleiner waren als die Eingabedatei, konnten auch benutzt werden. Sie wurden dann eben wiederholt. Ich muss mal schauen, ob ich das wieder finde.
Bild
Blitzer
Beiträge: 79
Registriert: 26.09.2004 14:33
Wohnort: Lower Saxony

Re: Vernam Verschlüsselung mittels XOR'en oder OTP(one time

Beitrag von Blitzer »

Ja, so isses.

Code: Alles auswählen

Procedure OTP_EncDec(*data.Character, *key.Character)
   Protected *k.Character = *key
   While *data\c
      *data\c ! *k\c
      *data + SizeOf(Character)
      If (*k\c = 0)
         *k = *key
      Else
         *k + SizeOf(Character)
      EndIf      
   Wend
 EndProcedure
Ich meine, hier fehlt noch die Integer-Abfrage ...
Antworten