Verzweifle an Ciphersaber-Verschlüsselung [gelöst]

Für allgemeine Fragen zur Programmierung mit PureBasic.
nueh
Beiträge: 12
Registriert: 12.05.2013 18:57
Wohnort: Bremen

Verzweifle an Ciphersaber-Verschlüsselung [gelöst]

Beitrag von nueh »

Hallo Alle,

ich versuche diesen Code http://www.purebasic.fr/english/viewtop ... 01#p374501 dazu zu bringen, die Testdateien von http://ciphersaber.gurus.org zu entschlüsseln.
Bisher vergeblich :evil:

Code: Alles auswählen

Procedure decrypt(mem, memLen, output, key, keyLen)

  If keyLen > 245
    keyLen = 245
  ElseIf keyLen < 0
    ProcedureReturn 0
  EndIf

  ; define state array, key array and 10 byte IV vector
  Dim S.a(255)
  Dim k.a(255)
  Dim V.a(9)

  ; setup index variables
  i.i = 0
  j.u = 0
  n.u = 0

  ; grab 10 byte initialization vector (IV) from beggining of mem
  For i = 0 To 9
    V(i) = PeekA(mem + i)
  Next
  mem = mem + 10

  ; put first 246 bytes of key into K array
  For i = 0 To keyLen
    k(i) = PeekA(key + i)
  Next

  ; add IV to end of user Key
  For i = 0 To 9
    k(keyLen + i) = V(i)
  Next
  keyLen = keyLen + 10

  ; set up state array
  For i = 0 To 255
    S(i) = i
  Next

  ; mix up the state array
  ;   For n = 1 To 10 ; 20 ist Standardwert von Ciphersaber-2, 10 wurde für die Testdatei 'cs2test1.cs2' benutzt
  For i = 0 To 255
    j    = (j + S(i) + k(i % keyLen)) % 255
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
  Next
  ;   Next

  ; ciphering operation
  j = 0
  i = 0

  For i = 0 To memLen
    i    = i % 255
    j    = (j + S(i)) % 255
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
    PokeA(output + i, S((S(i) + S(j)) % 255) ! PeekA(mem + i))
  Next

EndProcedure


If OpenConsole()
  key.s       = "asdfg"
  *KeyID      = AllocateMemory(Len(key))
  PokeS(*KeyID, key)

  length          = ?CSTEST1end - ?CSTEST1
  *OutputMemoryID = AllocateMemory(length-10) ; Dateilänge minus 10 IV-Bits

  If *OutputMemoryID
    decrypt(?CSTEST1, length, *OutputMemoryID, *KeyID, Len(key))
    WriteConsoleData(*OutputMemoryID, length-10)
  EndIf
EndIf


DataSection
  CSTEST1:
  Data.q $1967AAF3AB0B6D6F, $74CA77B6ED301503, $4385B8E7D09D08E0, $EFDB7CE34814BB56, $FDB35F4F4FA8F3E7
  CSTEST1end:
EndDataSection
Wäre großartig, wenn jemand einen Tipp hätte.
Viele Grüße,
Niklas
Zuletzt geändert von nueh am 06.04.2015 18:30, insgesamt 1-mal geändert.
PureBasic 5.40 LTS (x64), MacBook Air, Mac OS X 10.11.1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von NicTheQuick »

Da sind viele Fehler drin.
1.
Der Code wird erstmal nur funktionieren, wenn Unicode ausgeschaltet ist.

2.

Code: Alles auswählen

*KeyID      = AllocateMemory(Len(key))
Da fehlt ein + 1 wegen dem Nullbyte:

Code: Alles auswählen

*KeyID      = AllocateMemory(Len(key) + 1)
3.

Code: Alles auswählen

*OutputMemoryID = AllocateMemory(length - 10) ; Dateilänge minus 10 IV-Bits
10 Bytes sollte man hier auf keinen Fall abziehen, denn diese Schleife...

Code: Alles auswählen

  For i = 0 To memLen
    i    = i % 255
    j    = (j + S(i)) % 255
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
    PokeA(output + i, S((S(i) + S(j)) % 255) ! PeekA(mem + i))
  Next
...schreibt (memLen + 1) Bytes an die Adresse in *OutputMemoryID. Das heißt sogar eins mehr als es darf.
Demnach muss man entweder das hier machen:

Code: Alles auswählen

*OutputMemoryID = AllocateMemory(length + 1) ; Dateilänge + 1
oder das hier

Code: Alles auswählen

*OutputMemoryID = AllocateMemory(length) ; Dateilänge
und dann auch das hier

Code: Alles auswählen

  For i = 0 To memLen - 1 ;hier ist eine -1 dazu gekommen!
    i    = i % 255
    j    = (j + S(i)) % 255
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
    PokeA(output + i, S((S(i) + S(j)) % 255) ! PeekA(mem + i))
  Next
Aber auch dann kommt nichts sinnvolles raus am Ende, aber zumindest läuft dann das Programm.
nueh
Beiträge: 12
Registriert: 12.05.2013 18:57
Wohnort: Bremen

Re: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von nueh »

Danke für die schnelle Antwort.
Durch die Fehler bei der Speicherverwaltung sollte ja eigentlich nur Unsinn am Ende der korrekt entschlüsselten Datei stehen, oder? Ich fürchte, ich habe beim Verschlüsselungsalgorithmus etwas verbockt.

Wenn ich das richtig sehe, wird hier:

Code: Alles auswählen

; grab 10 byte initialization vector (IV) from beggining of mem
  For i = 0 To 9
    V(i) = PeekA(mem + i)
  Next
  mem = mem + 10
der Zeiger um 10 Bytes verschoben. Durch die um 11 Schritte zu lange Schleife

Code: Alles auswählen

For i = 0 To memLen
    i    = i % 255
    j    = (j + S(i)) % 255
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
    PokeA(output + i, S((S(i) + S(j)) % 255) ! PeekA(mem + i))
  Next
wird ans Ende von 'output' Unsinn geschrieben. Aber der Anfang müsste doch stimmen!?
PureBasic 5.40 LTS (x64), MacBook Air, Mac OS X 10.11.1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von NicTheQuick »

Ich hab's mal grad selbst programmiert nach dieser Anleitung. Es funktioniert. Vielleicht findest du selbst raus, wann an deiner Procedure noch falsch ist. Meine Version funktioniert jetzt auch mit Unicode.

Code: Alles auswählen

EnableExplicit

; Output has to be 10 bytes larger than input for encoding
; Output will be 10 bytes less than input for decoding
Procedure CS_encode(*key.Ascii, keyLength.i, *input.Ascii, inputLength.i, *output.Ascii, rounds.i = 1, encode.i = #True)
	Protected Dim S.a(255), Dim S2.a(255)
	Protected i.i, j.i, n.i, *random
	
	If (keyLength > 246)
		ProcedureReturn #False
	EndIf
	
	For i = 0 To 255
		S(i) = i
	Next
	
	CopyMemory(*key, @S2(0), keyLength)
	
	If (encode)
		RandomData(*output, 10)
		*random = *output
		*output + 10
	Else
		*random = *input
		*input + 10
		inputLength - 10
	EndIf
	
	CopyMemory(*random, @S2(keyLength), 10)
	
	For i = keyLength + 10 To 255
		S2(i) = S2(i - keyLength - 10)
	Next
	
	For n = 1 To rounds
		For i = 0 To 255
			j = (j + S(i) + S2(i)) % 256
			Swap S(i), S(j)
		Next
	Next
	
	i = 0
	j = 0
	While inputLength
		i = (i + 1) % 256
		j = (j + S(i)) % 256
		Swap S(i), S(j)
		n = (S(i) + S(j)) % 256
		*output\a = *input\a ! S(n)
		*input + 1
		*output + 1
		inputLength - 1
	Wend
	
	ProcedureReturn #True
EndProcedure

Procedure CS_decode(*key.Ascii, keyLength.i, *input.Ascii, inputLength.i, *output.Ascii, rounds.i = 1)
	ProcedureReturn CS_encode(*key, keyLength, *input, inputLength, *output, rounds, #False)
EndProcedure

If OpenConsole()
	; Eingabe
	Define key.s = "asdfg"
	Define inputLength.i = ?CSTEST1end - ?CSTEST1
	Define *input = ?CSTEST1
	
	; Verarbeitung
	Define *key = AllocateMemory(Len(key))
	PokeS(*key, key, -1, #PB_Ascii | #PB_String_NoZero)
	
	Define *output = AllocateMemory(inputLength - 10)
	
	CS_decode(*key, Len(key), *input, inputLength, *output)
	
	Define output.s = PeekS(*output, inputLength - 10, #PB_Ascii)
	
	;Ausgabe
	PrintN(output)
	Input()
EndIf


DataSection
	CSTEST1:
		Data.a $6f, $6d, $0b, $ab, $f3, $aa, $67, $19,
		       $03, $15, $30, $ed, $b6, $77, $ca, $74,
		       $e0, $08, $9d, $d0, $e7, $b8, $85, $43,
		       $56, $bb, $14, $48, $e3, $7c, $db, $ef,
		       $e7, $f3, $a8, $4f, $4f, $5f, $b3, $fd 
	CSTEST1end:
EndDataSection
Edit:
Du hast überall Modulo 255 gemacht, obwohl es 256 sein muss.
Die Schleife muss zum Dekodieren so aussehen:

Code: Alles auswählen

For i = 0 To memLen - 11 ;hier ein -11 statt -1
    i    = i % 256
    j    = (j + S(i)) % 256
    temp = S(i)
    S(i) = S(j)
    S(j) = temp
    PokeA(output + i, S((S(i) + S(j)) % 256) ! PeekA(mem + 10 + i)) ;hier ein +10
  Next
Du hast vergessen das Array k() bis zum Ende aufzufüllen.
nueh
Beiträge: 12
Registriert: 12.05.2013 18:57
Wohnort: Bremen

Re: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von nueh »

Danke. Jetzt muss ich erstmal nachdenken ...
PureBasic 5.40 LTS (x64), MacBook Air, Mac OS X 10.11.1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von NicTheQuick »

Hier zum Spaß noch ein Bruteforce mit dem verschlüsselten Text von http://ruletheweb.co.uk/blog/2014/04/ciphersaber/ und den 25 häufigsten Passwörtern von 2013.

Code: Alles auswählen

Procedure isValidText(*text.Ascii, length.i)
	While length
		If (*text\a < 32 Or *text\a > 128) And (Not (*text\a = 13 Or *text\a = 10))
			ProcedureReturn #False
		EndIf
		*text + 1
		length - 1
	Wend
	ProcedureReturn #True
EndProcedure

If OpenConsole()
	; Eingabe
	Define key.s = "asdfg"
	Define inputLength.i = ?CSTEST1end - ?CSTEST1
	Define *input = ?CSTEST1
	
	; Verarbeitung
	Define *key = AllocateMemory(Len(key))
	PokeS(*key, key, -1, #PB_Ascii | #PB_String_NoZero)
	
	Define *output = AllocateMemory(inputLength - 10)
	
	CS_decode(*key, Len(key), *input, inputLength, *output)
	
	Define output.s = PeekS(*output, inputLength - 10, #PB_Ascii)
	
	; Ausgabe
	PrintN(output)
	
	; Bruteforce-Test
	PrintN("Bruteforcing the code on http://ruletheweb.co.uk/blog/2014/04/ciphersaber/")
	inputLength = ?CS_BruteforceEnd - ?CS_Bruteforce
	*input = ?CS_Bruteforce
	*output = ReAllocateMemory(*output, inputLength - 10)
	Restore passwords2013
	Repeat
		Read.s key
		If (key = "") : Break : EndIf
		Define *key = ReAllocateMemory(*key, Len(key))
		PokeS(*key, key, -1, #PB_Ascii | #PB_String_NoZero)
		CS_decode(*key, Len(key), *input, inputLength, *output, 20)
		If isValidText(*output, inputLength - 10)
			PrintN("Valid key found: '" + key + "'")
			PrintN("Decrypted Text:")
			output = PeekS(*output, inputLength - 10, #PB_Ascii)
			PrintN(output)
		Else
			PrintN("Wrong key: '" + key + "'")
		EndIf
	ForEver
	Input()
	CloseConsole()
EndIf


DataSection
	CSTEST1:
		Data.a $6f, $6d, $0b, $ab, $f3, $aa, $67, $19,
		       $03, $15, $30, $ed, $b6, $77, $ca, $74,
		       $e0, $08, $9d, $d0, $e7, $b8, $85, $43,
		       $56, $bb, $14, $48, $e3, $7c, $db, $ef,
		       $e7, $f3, $a8, $4f, $4f, $5f, $b3, $fd 
	CSTEST1end:
	passwords2013:
		Data.s "123456", "password", "12345678", "qwerty", "abc123", "123456789", "111111", "1234567",
		       "iloveyou", "adobe123", "123123", "admin", "1234567890", "letmein", "photoshop", "1234",
		       "monkey", "shadow", "sunshine", "12345", "password1", "princess", "azerty", "trustno1", "000000", ""
	CS_Bruteforce:
		Data.a $f8, $a2, $76, $5d, $d2, $3a, $75, $67, $0f, $15, $ea, $1e, $8d, $55, $9f, $39,
		       $69, $cd, $3f, $d6, $61, $48, $06, $85, $65, $1e, $a3, $1a, $eb, $d7, $88, $dd,
		       $d8, $cd, $46, $e8, $0c, $d6, $cd, $2d, $b1, $bf, $7b, $34, $aa, $fc, $aa, $ed,
		       $39, $a9, $14, $6f, $e7, $5c, $57, $f6, $23, $f8, $69, $d3, $17, $f7, $0a, $f8,
		       $a8, $7d, $29, $f3, $9c, $e7, $45, $51, $0d, $6c, $92, $b8, $9f, $3d, $6c, $5a,
		       $c8, $8c, $7d, $71, $e0, $60, $75, $fb, $00, $61, $c6, $f2, $02, $60, $e3, $38,
		       $ab, $c0, $48, $f7, $ed, $bd, $05, $67, $c0, $25, $99, $cc, $85, $67, $23, $ae,
		       $67, $61, $e2, $0c, $ce, $90, $95, $c8, $8a, $9f, $19, $ca, $2e, $35, $0b, $a8,
		       $c3, $31, $6a, $39, $3a, $24, $52, $31, $e4, $81, $ae, $35, $f6, $d9, $c7, $5f,
		       $31, $3e, $6f, $2f, $2f, $96, $87, $95, $0c, $2f, $90, $87, $1f, $a2, $94, $68,
		       $e3, $ac, $93, $29, $4d, $a7, $53, $24, $a1, $ca, $51, $35, $10, $84, $50, $58,
		       $01, $12, $42, $6a, $6a, $0b, $f4, $1d, $a6, $33
	CS_BruteforceEnd:
EndDataSection 
nueh
Beiträge: 12
Registriert: 12.05.2013 18:57
Wohnort: Bremen

Re: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von nueh »

Nochmals Danke für deine Hilfe, mein Programm läuft jetzt.

Aber in deinem Code habe ich etwas nicht verstanden:

Code: Alles auswählen

*output\a = *input\a ! S(n)
Wieso sind denn *output und *input auf einmal Arrays? Und was bedeutet das a?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von NicTheQuick »

*input und *output sind Pointer und haben die Struktur Ascii. Dadurch kann man auf genau 1 vorzeichenloses Byte zugreifen. Und zwar an der Stelle, auf die der Pointer zeigt.
Das sind also keine Arrays. Durch das *input + 1 wird der Pointer einfach immer nur auf das nächste Byte verschoben.
nueh
Beiträge: 12
Registriert: 12.05.2013 18:57
Wohnort: Bremen

Re: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von nueh »

Aha, wo kann ich denn etwas über die Ascii-Struktur und eventuelle weitere lesen? Die Hilfe und Google waren bislang nicht mehr ergiebig.
Jetzt höre ich auch auf zu fragen, versprochen.

Schönen Abend,
Niklas
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
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: Verzweifle an Ciphersaber-Verschlüsselung

Beitrag von NicTheQuick »

Du sollst hier nicht vom Fragen abgehalten werden. Unter Werkzeuge -> Strukturverzeichnis findest du alle Strukturen. Im Grunde ist die Ascii-Struktur einfach das hier:

Code: Alles auswählen

Structure Ascii
    a.a
EndStructure
Ich glaube das, was dich eher verwirrt, sind die Pointer selbst. Oder nicht?
Antworten