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



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


Log in to reply