Blowfish - Verschlüsselung



  • Hallo alle!

    Ich habe gestern nach viel hin und her OpenSSL-0.9.6c endlich kompiliert 😃

    Ich habe dann mit Hilfe von Kollege und der Dokumentation eine Funktion geschrieben, die jedes mal einen Blowfish-Schlüssel erzeugt und einen String damit verschlüsselt:

    AnsiString BlowfishString(AnsiString data, AnsiString pwd, bool encode)
    /*
      Data wird mit Blowfish verschlüsselt
    
      pwd sind die Grunddaten für den Schlüssel
    */
    {
       //pwd wird in einen null-terminierten String umgewandelt
       unsigned char* ch = pwd.c_str();
       //Länge des Strings
       int l = strlen(ch);
       //Deklaration des Schlüssels
       BF_KEY key;
       //Der Schlüssel key wird generiert
       BF_set_key(&key, l, ch);
    
       /* Wird von OpenSSL verlangt
          "ivec must point at an 8 byte long initialization vector"
          es genügt, wenn man ivec nur deklariert
       */
       unsigned char ivec;
       /* Wird von OpenSSL verlangt
          "num must point at an integer which must be initially zero"
          zeigt auf das byte, das verschlüsselt wird/wurde
       */
       int num = 0;
    
       AnsiString password = data;
    
       //Verschlüsselung mit Blowfish
       //bei encode == true wird verschlüsselt
       if (encode)
          BF_cfb64_encrypt(password.c_str(), password.c_str(),
                          strlen(password.c_str()), &key, &ivec, &num, BF_ENCRYPT);
       //sonst entschlüsselt
       else
          BF_cfb64_encrypt(password.c_str(), password.c_str(),
                          strlen(password.c_str()), &key, &ivec, &num, BF_DECRYPT);
    
       data = password;
    
       return data;
    }
    

    Eigentlich klappt das ganze sehr gut... Mit einem TForm Fenster

    Ich habe eine Anwendung mit vier TForms. In der ersten wird ein Passwort mit Blowfish verschlüsselt und in einer Datenbank gespeichert.
    Im nächsten Fenster, wird nun das verschlüsselte Passwort aus der Datenbank geladen und mit dem gleichen Schlüssel entschlüsselt.
    Aber die Entschlüsselung klappt nicht, das Passwort aus der DB wird nicht zurück verschlüsselt 😕

    Kann mir jemand bitte helfen?



  • Dein unsigned char ch* ist quasi eine Zufallszahl.
    Siehe FAQ unter "AnsiString"



  • Danke, Jansen 🙂

    Ich habe den Code geändert:

    AnsiString BlowfishString(AnsiString data, AnsiString dataKey, bool encode)
    /*
      Data wird mit Blowfish verschlüsselt
    
      pwd sind die Grunddaten für den Schlüssel
    */
    {
       //dataKey wird in einen null-terminierten String umgewandelt
       unsigned char* ch = new char[dataKey.Length()+1];
       //ch muss erstellt werden, da es sonst zu unterschiedlich Verschlüsselungen
       //in verschiedenen TForms kommt
       strcpy(ch, dataKey.c_str());
       //Länge des Strings
       int l = (int) strlen(ch);
       //Deklaration des Schlüssels
       BF_KEY key;
       //Der Schlüssel key wird generiert
       BF_set_key(&key, l, ch);
    
       /* Wird von OpenSSL verlangt
          "ivec must point at an 8 byte long initialization vector"
          es genügt, wenn man ivec nur deklariert
       */
       unsigned char ivec;
       /* Wird von OpenSSL verlangt
          "num must point at an integer which must be initially zero"
          zeigt auf das byte, das verschlüsselt wird/wurde
       */
       int num = 0;
    
       unsigned char* in = new char[data.Length()+1];
       strcpy(in, data.c_str());
       long length = (long) strlen(data.c_str());
       BF_KEY *schedule = &key;
       //Verschlüsselung mit Blowfish
       //bei encode == true wird verschlüsselt
    
       if (encode)
          BF_cfb64_encrypt(in, in, length, schedule, &ivec, &num, BF_ENCRYPT);
       //sonst entschlüsselt
       else
          BF_cfb64_encrypt(in, in, length, schedule, &ivec, &num, BF_DECRYPT);
    
       AnsiString s = StrPas(in);
    
       delete [] in;
       delete [] ch;
    
       return s;
    }
    

    Ich definiere in der Headerdatei noch

    const AnsiString KEY = "1234567890123456";
    

    Und dann rufe ich die Funktion auf:

    AnsiString s = BlowfishString(s, KEY, true);
    

    Wenn ich s verschlüsseln will.

    Ich kriege aber trotzdem noch unterschiedlich Werte für es jedesmal. Also habe ich den Debugger benutzt. Der sagt mir, dass die Speicheradresse von ch im Aufruf von "BF_cfb64_encrypt(in, in, length, schedule, &ivec, &num, BF_ENCRYPT);" ändert.

    Ich weiß wirklich nicht, wo mein Fehler ist. Hat jemand noch eine Idee?



  • Möglich, dass die Funktion BF_cfb64_encrypt() fehlerhaft ist, oder hast Du auch mal die Übergabeparameter gecheckt, so, dass alles richtig in der Funktion gesetzt ist?

    Generell ist zu sagen, dass man das Passwort eher nicht mit einem Crypt-Algo verschlüsseln sollte. Eleganterweise nimmt man dazu einen Hash-Algorithmus, wie z.B. MD5 oder SHA. Dieser erzeugt von einer bel. Zeichenfolge eine eindeutige Hash-Summe, die man dann in der DB speichert und bei Bedarf mit der neuen Hash-Summe im Anmeldefenster vergleicht.

    Schau mal auf meiner Seite unter BCB->Verschlüsselung.



  • Danke, F98.

    Ich habe das Problem gelöst indem ich die DCPcrypt Komponente benutze statt OpenSSL. MD5 habe ich bereits eingebaut, aber ich brauche einen guten Verschlüsselungalgorithmus um andere Daten als das Passwort in einer Datenbank zu soeichern.


Anmelden zum Antworten