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.
    }
    

Anmelden zum Antworten