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



  • @Zhavok Private Chats soll der Server wohl besser nicht mitlesen können.



  • @Swordfish Das eine schließt das andere ja nicht aus. Die Nachrichten können trotzdem auf dem Server mit AES verschlüsselt werden. Jedoch nur die Verschlüsselung mit AES wie bei deinem Link halte ich für Sergey Fährlich. Spätestens beim Schlüsselaustausch können schnell Fehler entstehen. Und wenn ich in einem Chat angemeldet bin, wo von Privatchat-Verschlüsselung die Rede ist, verlasse ich mich auf eine saubere Implementation von Leuten, die sich auf dem Gebiet auskennen. Sowas sollte man einfach nie selbst schreiben.



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

    Die Nachrichten können trotzdem auf dem Server mit AES verschlüsselt werden.

    Das sollte wohl beim Client passieren bevor der Server die Nachricht über eine TLS-gesicherte Verbindung bekommt.

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

    Und wenn ich in einem Chat angemeldet bin, wo von Privatchat-Verschlüsselung die Rede ist, verlasse ich mich auf eine saubere Implementation von Leuten, die sich auf dem Gebiet auskennen. Sowas sollte man einfach nie selbst schreiben.

    Ähm. Der Link zeigt die Verwendung von crypto++ und redet nicht von Selberschreiben.



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

    Ähm. Der Link zeigt die Verwendung von crypto++ und redet nicht von Selberschreiben.

    Und was macht man mit lediglich einer AES Verschlüsselung wenn man einen Chat vor Mitlesenden schützen will?



  • Hast ja recht. Besser RSA ^^
    War eben das erstbeste Beispiel zur Verwendung von crypto++ das mir über den Weg gelauft ist.



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

    Hast ja recht. Besser RSA ^^

    Zum Beispiel. Das Problem bei asymmetrischen Verfahren, ist halt leider die Geschwindigkeit (RSA ist 100 mal langsamer als AES). Für einen Chat ist das sicher ausreichend, aber falls du (@Hirnfrei ) noch irgendwann Up-/Downloads hinzufügen möchtest, würde ich ein hybrides Verfahren benutzen.







  • Ach herrje, 2 Minuten nicht reingeschaut und schon musste ich ein ganzer Roman lesen!

    Erstmal danke für die Hinweise. RSA würde mir persönlich auch sehr gut gefallen. Oder OTR. Wobei es im Prinzip nur Spielerei ist. Ich wage es zu bezweifeln, dass dieses Programm grosse Verwendung finden wird. Ist eigentlich nur für eine Gruppe von uns hier gedacht und auch mehr aus einem Kneipengespräch was damit begann, dass man bei WhatsApp nie Termine abmachen sollte, da in Gruppen ohnehin so viel Schwachsinn geschrieben wird, dass wenn man nicht dauernd mitliest ganz schnell Termine verbummelt. Also selbst wenn es nicht so sicher ist, dass der BND nicht mitlesen kann, ist das auch kein Beinbruch. Mich reizt es jetzt aber, da auch eine Verschlüsslung einzubauen.

    Wo ich aber Wert drauf lege ist ganz klar, die Nachrichten sollen lokal verschlüsselt und entschlüsselt werden. Der Server soll damit nichts zu tun haben. Eben End-2-End.

    Ich kann nicht ausschliessen, dass da auch mal Bilder drüber sollen. Was würdest du dafür denn empfehlen und kannst du mich da auch auf den Weg bringen? Wie schon angemerkt, ich bin Neuling auf dem Gebiet.



  • Naja, das haben @Zhavok und ich ja grade durchgekaut:

    Public chat: Jeder Client sendet/empfängt zum/vom Server über eine mit TLS gesicherte Verbindung. Server verteilt die Nachrichten an die anderen Clients
    Private chat: Server vermittelt die IPs der Partner, Partner tauschen den mit irgendeinem Public-Key Verfahren (zB. RSA) verschlüsselten Session-Key, weitere Kommunikation findet Client-to-Client mit einem synchronen Verschlüsselungsverfahren (zB. AES) statt.



  • Wie sieht es denn mit GnuPG aus? Wäre das ratsam?



  • Also, GnuPG scheine ich zu verstehen. Nur hinter eins steige ich nicht. Was genau ist da jetzt der private und was der öffentliche Schlüssel?





  • also eigentlich verwendet man aes und den schlüssel dafür tauscht man über rsa aus. 😉

    soweit ich weiß kann man beides über openssl oder den windows crypto provider bekommen.



  • Also wenn ich das richtig verstanden habe, generiert GnuPG einen privaten und einen öffentlichen Schlüssel. In der Dokumentation wird aber von primary und sub gesprochen. Bin ich gerade am ausprobieren. Ich möchte ungerne den Schlüssel zum entschlüsseln verschicken müssen. Der soll schön auf dem lokalen System bleiben.


  • Mod

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

    Also wenn ich das richtig verstanden habe, generiert GnuPG einen privaten und einen öffentlichen Schlüssel. In der Dokumentation wird aber von primary und sub gesprochen. Bin ich gerade am ausprobieren. Ich möchte ungerne den Schlüssel zum entschlüsseln verschicken müssen. Der soll schön auf dem lokalen System bleiben.

    RTFM!?
    https://wiki.debian.org/Subkeys



  • Danke @SeppJ. Wieder was gelernt!

    Aber, ich muss um Rat fragen. Ich bin gerade dabei mir eine Funktion zu bauen, die ein Schlüsselpaar generiert. Da sieht bislang so aus:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <gpgme.h>
    
    #include "t-support.h"
    
    gpgme_error_t gpgErr;
    
    gpgme_key_t prKey = NULL;
    gpgme_key_t puKey = NULL;
    
    bool keyGEN(string name, string email)
    {
    	gpgme_ctx_t ctx;
    	char *parms;
    	gpgme_genkey_result_t result;
    	gpgme_data_t out;
    	gpgme_key_t ekey[2] = {NULL, NULL};
    	
    	size_t csize = strlen("<GnupgKeyParms format=\"internal\">\n") + 2 +
    							strlen("Key-Type: RSA\n") + 2 +
    							strlen("Key-Length: 2048\n") + 2 +
    							strlen("Subkey-Type: ELG-E\n") + 2 +
    							strlen("Subkey-Length: 2048\n") + 2 +
    							strlen("Name-Real: \n") + 2 +
    							strlen(name.c_str()) + 2 +
    							strlen("Name-Comment: (pp=abc)\n") + 2 +
    							strlen("Name-Email: \n") + 2 +
    							strlen(email.c_str()) + 2 +
    							strlen("Expire-Date: 0\n") + 2 +
    							strlen("</GnupgKeyParms>\n") + 2;
    							
    	parms = (char *) malloc(csize);
    
    	sprintf(parms, "<GnupgKeyParms format=\"internal\">\n\
    Key-Type: RSA\n\
    Key-Length: 2048\n\
    Subkey-Type: ELG-E\n\
    Subkey-Length: 2048\n\
    Name-Real: %s\n\
    Name-Comment: (pp=abc)\n\
    Name-Email: %s\n\
    Expire-Date: 0\n\
    Passphrase: abc\n\
    </GnupgKeyParms>\n", name.c_str(), email.c_str());
    					
    	init_gpgme(GPGME_PROTOCOL_OpenPGP);
    
    	gpgme_set_armor(ctx, 1);
      
      	gpgErr = gpgme_new(&ctx);
    	if(gpgErr) return false;
    
    	gpgErr = gpgme_op_genkey(ctx, parms, NULL, NULL);
    	if(gpgErr) return false;
      
    	result = gpgme_op_genkey_result(ctx);
    
    	if(!result)
    	{
    		fprintf(stderr, "%s:%d: gpgme_op_genkey_result returns NULL\n", __FILE__, __LINE__);
    		return false;
    	}
    	
    	gpgErr = gpgme_get_key(ctx, result->fpr, &puKey, 0);
    	if(gpgErr) return false;
    
    	ekey[0] = puKey;
    
    	gpgErr = gpgme_op_export_keys(ctx, ekey, 0, out);
    	if(gpgErr) return false;
    
      	free(parms);
    	
    	return true;
    }
    

    Soweit funktioniert das auch, bis runter zu:

    gpgErr = gpgme_op_export_keys(ctx, ekey, 0, out);
    

    Da bekomme ich die Fehlermeldung:

    GPGME: Ungültiger Wert
    

    In der Beschreibung habe ich nun gelesen, diese Meldung heisst folgendes:

    if the operation completed successfully, GPG_ERR_INV_VALUE if keydata is not a valid empty data buffer
    

    Nachzulesen hier.

    Ich komme aber echt nicht hinter das Problem. Wie man im Code ja sehen kann, habe ich out nur deklariert. Da steht nichts drin und sie ist vom korrekten Typ. Aus Spass habe ich mal ein Beispiel zum exportieren von Keys compiliert und da kommt der gleiche Fehler.

    Hat jemand eine Idee?



  • Du must erst noch eine der Creating Data Buffers-Funktionen benutzen (gpgme_data_t ist ein Handle, s. 6 Exchanging Data).

    PS: Was soll deine komische strlen-Berechnung (mit jeweils +2)?



  • Geil, danke! Wieder was gelernt.

    Das mit strlen ist wohl eine Macke, die ich mir seit meinen Anfängen in C behalten habe. Aus irgendeinem Grund liebe ich es, Speicher anzufordern, zu belegen und wieder freizugeben. Frag mich nicht warum. Die +2 kommen daher, normalerweise baue ich zu allem, was ich an Speicher anforder, noch eine 1 hinzu. Das reicht hier aber irgendwie nicht. Also +2. Sicher ist sicher. Bist nicht der Erste, der mich danach gefragt hat 😉


  • Mod

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

    Geil, danke! Wieder was gelernt.

    Das mit strlen ist wohl eine Macke, die ich mir seit meinen Anfängen in C behalten habe. Aus irgendeinem Grund liebe ich es, Speicher anzufordern, zu belegen und wieder freizugeben. Frag mich nicht warum. Die +2 kommen daher, normalerweise baue ich zu allem, was ich an Speicher anforder, noch eine 1 hinzu. Das reicht hier aber irgendwie nicht. Also +2. Sicher ist sicher. Bist nicht der Erste, der mich danach gefragt hat 😉

    Die ganze Methode ist sowieso ein schrecklicher Mischmasch aus C und C++. In C kann das nicht funktionieren und in C++ sollte es nicht funktionieren, außer du hast einen sehr laxen Compiler. Auf jeden Fall ist es falsch und du hast nur Glück, wenn es trotzdem funktioniert (oder Pech, weil du dadurch deinen Fehler nicht bemerkst). Entferne mal alles string, das ist C++. Und mach den Cast beim malloc weg. Wenn dein Compiler dann über das malloc meckert, dann ist es ein C++-Compiler, den du nicht für C benutzen solltest.


Anmelden zum Antworten