RC4 encryption in C# to C/C++
-
C_Cheaf schrieb:
@~fricky: Danke für den hilfreichen Tipp! Das erklärt wahrscheinlich, warum ich nichts gefunden habe ^^
ne, du musst irgendwas falsch gemacht haben. wenn ich suche:
--> http://www.google.com/search?hl=en&q=rc4&btnG=Search
finde ich als ersten eintrag:
--> http://en.wikipedia.org/wiki/RC4
und etwa in der mitte der seite ist gleich ein quellcode.
-
C_Cheaf schrieb:
[...] und wenn man delete auskommentiert, wird der String falsch ver/entschlüsselt.
Wahrschenlich wird der Code in jedem Fall falsch ver/entschlüsselt nur das Du das im Crash nicht mehr sehen kannst.
Der Fehler kann auch in dem aufrufenden Code liegen, z.B. wenn content und key nicht richtig initialisiert sind. Das Problem mit Speicherzugriffsfehlern ist ja, daß die Fehlermeldung nur sagt wo der Speicher beschädigt war, nicht durch was.
-
@loks: Ich habe auch das Gefühl, dass mit dem Code etwas nicht stimmt...
Hmmm... Irgend etwas habe ich falsch verstanden fürchte ich.
Ich habe jetzt den Code, den ~fricky gepostet hat getestet. Aber ich bekomme das immer noch nicht richtig hin:
strcpy(test_string,"Das ist ein Test!"); prepare_key((unsigned char*)"12345678912345678",17,&key); printf("%s\n",test_string); rc4((unsigned char*)test_string,17,&key); printf("%s\n",test_string); rc4((unsigned char*)test_string,17,&key); printf("%s\n",test_string);
Am Ende sollte wieder "Das ist ein Test!" ausgegeben werden. Doch leider kommt etwas völlig anderes heraus.
Kann ich als Schlüssel irgend einen beliebigen Schlüssel verwenden? Muss der Schlüssel genau so lang sein wie der zu verschlüsselnde Text?
-
probier's mal mit dem aus dem wikipedia-artikel:
unsigned char S[256]; unsigned int i, j; /* KSA */ void rc4_init(unsigned char *key, size_t key_length) { for (i = 0; i < 256; i++) S[i] = i; for (i = j = 0; i < 256; i++) { unsigned char temp; j = (j + key[i % key_length] + S[i]) & 255; temp = S[i]; S[i] = S[j]; S[j] = temp; } i = j = 0; } /* PRGA */ unsigned char rc4_output() { unsigned char temp; i = (i + 1) & 255; j = (j + S[i]) & 255; temp = S[i]; S[i] = S[j]; S[j] = temp; return S[(S[i] + S[j]) & 255]; } #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { unsigned char text[] = "Das ist ein Test!"; // original int length = sizeof(text); unsigned char key[] = "Key"; // key unsigned char encrypted[256]; // verschlüsselt unsigned char decrypted[256]; // entschlüsselt int i; // verschlüsseln rc4_init (key, strlen(key)); for (i=0; i<length; i++) { encrypted[i] = text[i] ^ rc4_output(); printf ("%02x", encrypted[i]); } printf ("\n"); // entschlüsseln rc4_init (key, strlen(key)); for (i=0; i<length; i++) { decrypted[i] = encrypted[i] ^ rc4_output(); } decrypted[i] = 0; puts (decrypted); }
-
@~fricky: Wow der Code klappt!!! Vielen Dank!
Ich habe den Code noch etwas modifiziert. Ich habe alles in eine Funktion gepackt, um das ganze noch einfacher zu gestalten. Vielleicht hilft es dem ein oder anderen weiter:
void rc4_encryption(char* content, int content_length, char* key, int key_length) { unsigned char S[256]; //S-Box unsigned int i=0,j=0,n=0; //Laufvariablen unsigned char temp; //KSA (key-scheduling algorithm) - Berechnet die S-Box for(i=0;i<256;i++) {S[i] = i;} for (i=j=0;i<256;i++) { j = (j + key[i % key_length] + S[i]) & 255; temp = S[i]; S[i] = S[j]; S[j] = temp; } i=j=0; for (n=0; n<content_length; n++) //Läuft den gesamten Inhalt durch { //PRGA (pseudo-random generation algorithm) i = (i + 1) & 255; j = (j + S[i]) & 255; temp = S[i]; S[i] = S[j]; S[j] = temp; content[n] = content[n] ^ S[(S[i] + S[j]) & 255]; //XOR Verknüpfung mit dem Inhalt } }
-
C_Cheaf schrieb:
Ich habe den Code noch etwas modifiziert. Ich habe alles in eine Funktion gepackt, um das ganze noch einfacher zu gestalten. Vielleicht hilft es dem ein oder anderen weiter...
sehr gut. weiter so!
Talla schrieb:
Das ref in der Signatur heißt nichts anderes als dass eine Referenz auf das bytes Array übergeben wird.
ohne 'ref' zieht der compiler eine kopie vom ganzen array-inhalt? egal wie gross?
-
Ich tippe auf ein Problem mit dem Vorzeichen. Versuch es mal mit unsigned char.
-
~fricky schrieb:
Talla schrieb:
Das ref in der Signatur heißt nichts anderes als dass eine Referenz auf das bytes Array übergeben wird.
ohne 'ref' zieht der compiler eine kopie vom ganzen array-inhalt? egal wie gross?
Nein!
Arrays sind immer reference types. Der ref modifier ist hier total überflüssig (sozusagen pointer auf pointer).
-
gnarfield schrieb:
Arrays sind immer reference types.
ok, dann ist die welt ja in ordnung. hätte mich auch verblüfft, wenn's anders gewesen wäre.
-
Nur meiner Detailverliebheit willen... Im konkreten Beispiel ist der ref tatsächlich überflüssig weil nur der Inhalt des Arrays verändert wird. Anders wäre es wenn das Array selbst verändert wird.
Beispiel:
void TestRef(ref byte[] arr) { arr = new byte[5]; } void TestNoRef(byte[] arr) { arr = new byte[5]; } void main() { byte[] a = new byte[6]; TestNoRef(a); // Hier ist a.Length == 6. das von TestNoRef neu angelegte array wurde verworfen TestRef(ref a); // Hier ist a.Length == 5. Das usprüngliche array wurde verworfen. }