Nachrichten verschlüsseln für ein kleines Chat-Projekt



  • Aber wenn du sagst, der private Schlüssel wird nicht exportiert. Woher weiss mein Programm dann von dem Schlüssel, wenn es mal beendet war?



  • Dieser Beitrag wurde gelöscht!


  • @Hirnfrei

    also insgesamt könnte das so ablaufen, dass sich jeder client einmalig beim server registriert und dann vom server einen public key zugewiesen bekommt (um daten zum server zu senden) und dem server einen public key übergibt (um daten vom server zu empfangen).

    der server muss dann natürlich eine datenbank führen, wem welcher key gehört, damit alles ent- und verschlüsselt werden kann. wie das jetzt mit gnupg funktioniert, weiß ich leider nicht.



  • So ist das ja in etwa geplant. Bei der Registrierung wird ein Schlüsselpaar generiert. Der öffentliche Schlüssel wird in die Datenbank gespeichert, damit andere Teilnehmer ihn benutzen können um private Nachrichten zu verschlüsseln. Der private Schlüssel bleibt dabei auf dem lokalen Rechner. Den will ich zu keinem Zeitpunkt irgendwo in der Datenbank haben. Soweit kriege ich das ja auch schon hin. Die Schlüssel werden generiert, ich kann damit Nachrichten ver- und entschlüsseln. Auch das ex- und importieren des öffentlichen Schlüssel funktioniert.

    Aber eben, sobald ich das Programm beendet geht ja logischerweise auch der private Schlüssel verloren. Ihn zu exportieren klappt ja auch, inklusive einer Abfrage vom Passphrase. Nur eben, mein Programm muss ja nach einem Neustart auch den privaten Schlüssel wieder importieren können, sonst kann ich ja keine Nachrichten aus der letzten Sitzung mehr entschlüsseln. Daran kämpfe ich gerade.



  • @Hirnfrei

    gpg speichert die schlüssel nicht? sonst schreib sie doch beim beenden auf die festplatte.



  • Wo sollte gpg die speichern? Vielleicht ist mir da auch etwas entgangen, denn wie ich ja oben schon erwähnte, bin Anfänger in der Thematik.

    Speichern tu ich ja die Schlüssel. Laden klappt auch, aber wie ich jetzt merke scheint beim verschlüsseln etwas nicht zu funktionieren. Selbst wenn ich in der Routine, in der ich einen Text verschlüssele, die Ausgabe sofort entschlüssel will heisst es nur "Keine Daten". Also mache ich da irgendwas falsch, was keine Fehlermeldung verursacht.



  • @Hirnfrei

    tja also ich würde folgendes sagen: du kannst dir gar nicht vorstellen, was das für glücksgefühle auslöst, wenn man den fehler nach stunden-, tage- oder wochenlangem herumprobieren endlich gefunden hat. 😃 ich kann dir da jetzt jedenfalls nicht helfen.



  • Ich kenne das Glücksgefühl sehr gut! Hatte ich erst kürzlich, als ich endlich mein Programm mit Qt auf Windows zum laufen gebracht habe.



  • ja dann mal los! oder du lieferst einfach mal quelltexte, fehlerbeschreibungen usw. da werde ich dann zwar wahrscheinlich trotzdem genauso schlau sein wie du, aber vielleicht kann dir ja jemand anderes helfen, und wenn nicht, dann sei dir bewusst, dass du - nachdem du das problem gelöst hast - etwas kannst, das andere nicht können. manchmal ist das ziemlich viel wert. 😉



  • Also noch hat mich der Ehrgeiz fest im Griff. Ich will das jetzt selbst auf die Reihe kriegen, da lerne ich im Regelfall auch am Meisten dabei. Aber wer weiss, irgendwann strecke ich vielleicht die Hufe.



  • Yeah, ich bin dann an dem Punkt angelangt, wo ich ganz gerne das Handtuch werfen würde!

    Mit gpgme scheint irgendetwas nicht so wirklich zu stimmen, denke ich. Selbst die Beispiele wollen nicht funktionieren. Also habe ich auf gcrypt umgeschwenkt. Ist auch GnuPG, erschliesst sich mir jedoch deutlich schneller irgendwie und beim Testen mit den Beispielen klappt auch alles ganz hervorragend!

    Nur in einer Hinsicht werde ich nicht schlau. Vielleicht kennt sich ja hier jemand damit aus.

    bool keyGEN(const char *pp)
    {
        gcrypt_init();
    
        const char *fname = "key.rsa";
        FILE *lockf = fopen(fname, "wb");
    
        if(!lockf)
        {
            xerr("fopen() failed");
            return false;
        }
    
        gcry_error_t err = 0;
        gcry_sexp_t rsa_parms;
        gcry_sexp_t rsa_keypair;
    
        err = gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:2048)))");
    
        if(err)
        {
            xerr("gcrypt: failed to create rsa params");
            return false;
        }
    
        err = gcry_pk_genkey(&rsa_keypair, rsa_parms);
    
        if(err)
        {
            xerr("gcrypt: failed to create rsa key pair");
            return false;
        }
    
        gcry_cipher_hd_t aes_hd;
        get_aes_ctx(&aes_hd);
    
        size_t rsa_len = get_keypair_size(2048);
        void* rsa_buf = calloc(1, rsa_len);
    
        if(!rsa_buf)
        {
            xerr("malloc: could not allocate rsa buffer");
            return false;
        }
        gcry_sexp_sprint(rsa_keypair, GCRYSEXP_FMT_CANON, rsa_buf, rsa_len);
    
        err = gcry_cipher_encrypt(aes_hd, (unsigned char*) rsa_buf, rsa_len, NULL, 0);
    
        if(err) 
        {
            xerr("gcrypt: could not encrypt with AES");
            return false;
        }
    
        if(fwrite(rsa_buf, rsa_len, 1, lockf) != 1) 
        {
            perror("fwrite");
            xerr("fwrite() failed");
            return false;
        }
    
        gcry_sexp_release(rsa_keypair);
        gcry_sexp_release(rsa_parms);
        gcry_cipher_close(aes_hd);
        free(rsa_buf);
        fclose(lockf);
    
        return true;
    }
    
    Das ist meine Funktion, um ein Schlüsselpaar zu erstellen. Funktioniert einwandfrei! Wenn ich damit ein paar generiere kann ich es anschliessend problemlos wieder laden, mit dem öffentlichen Schlüssen einen Text verschlüssen und ihn auch wieder mit dem privaten Schlüssel entschlüssen. Funktioniert echt super!
    
    Nur hinter ein Geheimnis komme ich einfach nicht!
    
    Ich müsste den öffentlichen Schlüssen irgendwie als Zeichenkette bekommen. Das brauche ich, um ihn im Profil des Benutzer in der Datenbank zu hinterlegen. Dem folgt, nachdem ich den Schlüssel als Zeichenkette habe, muss ich ihn hinterher aus der Zeichenkette zum verschlüssel wieder nutzbar machen und hier scheitere ich leider kläglich.
    
    Hat jemand eine Idee?
    


  • Ich weiß zwar nicht warum es ein (menschenlesbarer) String sein muss damit Du den Schlüssel in eine Datenbank stecken kannst ... kodiere ihn in Base64.



  • also wenn du void* auf char* castest, hast du schonmal einen c-string. wenn du es statt dessen auf uint64_t* castest, kannst du es ganz toll in hexadezimaler darstellung speichern.



  • @Wade1234: Deine Antworten werden immer merkwürdiger...



  • @Swordfish sagte in Nachrichten verschlüsseln für ein kleines Chat-Projekt:

    Ich weiß zwar nicht warum es ein (menschenlesbarer) String sein muss damit Du den Schlüssel in eine Datenbank stecken kannst ... kodiere ihn in Base64.

    Es muss kein menschen lesbarer String sein. Ich könnte wohl im Prinzip einfach rsa_buf speichern. Da habe ich dann aber sowohl den öffentlichen, wie auch den privaten Schlüssel drin. Der Private hat aber in meinen Augen in der Datenbank nichts zu suchen.

    Den Key selbst könnte ich ja so herausfinden:

        err = gcry_sexp_new(&rsa_keypair, rsa_buf, rsa_len, 0);
        gcry_sexp_t pubk = gcry_sexp_find_token(rsa_keypair, "public-key", 0);
    
    

    Dann hätte ich den Key ja als gcry_sexp_t. Aber wie soll ich das in der Datenbank speichern und hinterher wieder abrufen? Damit tue ich mich schwer.



  • @Hirnfrei sagte in Nachrichten verschlüsseln für ein kleines Chat-Projekt:

    gcry_sexp_t

    also eine kurze recherche hat ergeben, dass das eine datenstruktur ist. guck doch mal mit dem debugger, ob du da irgendwie an die daten ran kommst.



  • @Hirnfrei Ich nix weiß was Deine Datenbank. Du schauen selbst was stehen in Dokumentation und wie speichern?



  • Okay, verstehe.



  • @Wade1234 sagte in Nachrichten verschlüsseln für ein kleines Chat-Projekt:

    also wenn du void* auf char* castest, hast du schonmal einen c-string. wenn du es statt dessen auf uint64_t* castest

    Ja. Und Du schaust Dir besser mal an was aliasing ist. Und was man darf oder besser sein lässt.


Anmelden zum Antworten