Bitfehler im Code?
-
Hi,
Seid ein paar Stunden such ich schon nach der Lösung meines Problems, aber finde absolut keine. Hoffe ihr habt ne Idee und ich schaffe es, das Problem ohne zu viel Code zu veranschaulichen.
Also, seid ein paar Woche beschäftige ich mit Kryptographie und dem Feistlnetzwerk/Blowfishalgorythmus. Hab vor ein paar Tagen meine eigene Version vom Feistelnetzwerk fertig geschrieben und wollte die heute erweitern.Das Problem:
Ich habe/will eine Funktion schreiben, die den Schlüssel automatisch, aufgrund der Klartextlänge und andere Parameter erstellt. Das klappt auch ganz gut, einzele Buchstaben werden auch prima Kodiert und Dekodiert. Aber wenn die Länge des Klartextes >= 4 ist, dann stimmt (bei z.B. einer Klartextlänge von 4 Buchstaben) der erste und der letzte Buchstabe nicht mehr. Komisch finde ich, dass es bei einzel Buchstaben ohne Probleme geht, bzw. bei einem statischen Key (z.B. immer = A) es auch IMMER (egal wie lang der Klartext ist) geht.Hier der Code, der den Key generiert:
void Kodieren::GenerateKey(unsigned int length) { //KeyIndex ist member von Kodieren und sagt wo man sich (beim Kodiere/Dekodiern) beim Schlüssel befindet //Key ist ebenfalls member KeyIndex = 0; for (unsigned int i = 0; i <= 14; i++) { Key[i] = (length*i + 50) >> 4 ; //max 4Bit pro Zeichen, bei >4 output Bit >8 = nicht nachvollziehbar //Key[i] = 65 >> 4; //Geht ohne Probleme.... } }Hier der Aufruf:
void Kodieren::StringKodieren(char *string, unsigned int runden, bool kodieren) { //bool kodieren, sagt ob kodiert oder dekodiert werden soll //string = Klartext bzw. zuKodieren String, unsigned char rechts = 0; unsigned char links = 0; unsigned int size = StringLength(string); //Stringlänge herausfinden GenerateKey(size); //Key generieren for (unsigned int i = 0; i < size; i++) { Aufteilen(string[i],&rechts, &links); //Zeichen[i] von String in 2, 4Bit Blöcke teilen for (unsigned int j = 0; j < runden; j++) //In X Rnden alles kodieren(mit Key XORNEN) { if (kodieren) feistel(&links,&rechts); //Kodieren if (!kodieren) feistel(&rechts,&links); //Umgekehrter Aufruf->Dekodieren } string[i] = Zusammensetzen(links,rechts); //Blöcke wieder zusammenbauen } }Hier die main Funktion
#include <iostream> #include "Kodieren.h" int main() { char string[256] = {'\0',}; Kodieren kod; std :: cout << "Geben Sie den zu verschluesselnden Text ein: " << std :: endl; std :: cin.getline(string,256); //KODIEREN/DEKODIERE sind defines kod.StringKodieren(string, 5, KODIEREN); std :: cout << string << std :: endl; kod.StringKodieren(string, 5 , DEKODIEREN); std :: cout << string << std :: endl; }Der Key ist immer gleich, ob ich kodiere oder dekodiere und das Programm (sollte), da es bei einem statischen Key bzw. eizel Buchstaben geht ohne Probleme Funktionieren, aber tuts ja halt nicht

Kann es sein, dass ich trotz der 4Bit irgendwo was unterschlage oder so?
Oder läuft vllt KeyIndex falsch, sodass ich einen andern Key zum Kodieren/Dekoieren verwende? Wobei das nicht sein kann, da KeyIndex bei Dekodieren und Kodiere am Ende immer gleich ist.Danke schonmal, wenn ihr noch Code braucht, sagt's

Edit:
Hier nochmal der Code, wo der Key benutzt wird://ganz einfache Funktion, willst erstmal nur probieren :D unsigned char Kodieren::VerbindeKey(unsigned char zeichen) { zeichen = zeichen^Key[KeyIndex]; //Die eigentliche Funktion, die mit Key verbindet KeyIndex++; if (KeyIndex > 14) KeyIndex = 0; //Wenn Schlüssel einmal durch, wieder von vorne return zeichen; } //Verrechnet die Blöcke (mit verschlüsselung) void Kodieren::feistel(unsigned char *links, unsigned char *rechts) { unsigned char LiAlt = *links; //Links speichern *links = *rechts; *rechts = LiAlt^VerbindeKey(*rechts); //rechts(mit Key) mit links XORnen
-
Ich bin mir nicht ganz sicher, aber möglicherweise gibt es Probleme, wenn die Schlüsselzeichen größer werden als 15 (Überläufe bei der XOR-Verrechnung).
-
Hmm,
Also ein Fehler, den ich noch gefunden habe ist, dass ich den (im gewissen Sinne) Schlüssel auch rückwärts anweden muss.
Bei 5 Runden wir ja immer mit Schlüssel 0,1,2,3,4 geXORt, dann mit 5,6,7,8,9 usw.
Durch die Erstellung des Keys, auf die Weise von mir kam es zu Bitzusammenstellungen wie (für die erste Runde, also Schlüssel 0,1,2,3,4) : 11,11,11,11,10.Bei dekodieren habe ich den Schlüssel dann (richtig)falsch herum angewand. Also so:
11,11,11,11,10Da kann dann ja aber nur murks rauskommen, da beim kodieren das letzte Zeichen des Buchstaben mit 10 geXORt wurde anstatt mit 11. Also muss ich den Schlüssel beim Dekodieren sozusagen umdrehen, also den Benutzen:
10,11,11,11,11Ist nen bissel kompliziert geschrieben, aber ich hoffe damit gehts nun bei mir. Muss nach weitern Bugs nochmal suchen.
Komisch finde ich nur, dass bei keinem, der mir vorliegenden Artikel zu dem Thema (sowohl mit, also auch ohne Code) auf diese Thematik eingegangen wird, da das Feistelnetzwerk immer nur mit einem Schlüssel wie "5" beschrieben wird...
Überall steht zwar, dass beim Dekodieren alles umgekehrt angewand wird, aber selbst bei Wikipedia in der Formel wird nicht der genau Rundenschlüssel gekennzeichnet.
-
Äh. Ich weiss nicht genau was du mit "max 4Bit pro Zeichen" meinst, aber wenn ichs mal so verstehe wie ich es eben verstehe...:
//Key[i] = (length*i + 50) >> 4 ; Key[i] = ((length*i + 50) & 0xF0) >> 4 ;
-
Wenn ich den Schlüssel mit einem Zeichen verbinde und eines der Beide (egal ob Schlüssel oder das Zeichen) länger als 4Bit ist,fällt unter Umständen ein Bit beim Verbinden weg. Dies hätte dann zur Folge, dass man den Code nur schlecht wieder dekodieren könnte.
Darum kürze ich den Teilschlüssel einfach, die restlichen Bit, die dabei wegfallen sind mir egal.
So haben die beiden Anweisungen (also deine und meine) den selben Effekt, ich sehe keinen Vorteil in der vorherigen Verbindung mit 0xF0 oder ich hab da was übersehen...
-
Pille456 schrieb:
Wenn ich den Schlüssel mit einem Zeichen verbinde und eines der Beide (egal ob Schlüssel oder das Zeichen) länger als 4Bit ist,fällt unter Umständen ein Bit beim Verbinden weg. Dies hätte dann zur Folge, dass man den Code nur schlecht wieder dekodieren könnte.
Darum kürze ich den Teilschlüssel einfach, die restlichen Bit, die dabei wegfallen sind mir egal.Und das machst du nicht konsequent genug. Der Ausdruck 'length*i+50' kann durchaus zu groß werden, um in einem Byte untergebracht zu werden. Und die dabei "überstehenden" Bits bleiben im fertigen Schlüssel stehen - mit genau den Konsequenzen, die du vermeiden wolltest.
-
Ok, hab ich doch was übersehen, danke.
Ich werds anpassen
-
Pille456 schrieb:
Wenn ich den Schlüssel mit einem Zeichen verbinde und eines der Beide (egal ob Schlüssel oder das Zeichen) länger als 4Bit ist,fällt unter Umständen ein Bit beim Verbinden weg. Dies hätte dann zur Folge, dass man den Code nur schlecht wieder dekodieren könnte.
Darum kürze ich den Teilschlüssel einfach, die restlichen Bit, die dabei wegfallen sind mir egal.
So haben die beiden Anweisungen (also deine und meine) den selben Effekt, ich sehe keinen Vorteil in der vorherigen Verbindung mit 0xF0 oder ich hab da was übersehen...Du kannst auch & 0xFF schreiben, oder nach dem Shiften & 0xF, auf jeden Fall musst du die "zuviel Bits" irgendwie wegbringen.