# Gruppenchat: Über HTTPS oder nicht?



## eMSch (27. Jun 2014)

Guten Tag

Ich möchte eine Art Gruppenchat entwickeln, so ähnlich wie z.B. die Gruppen bei Telegram oder WhatsApp, das Augenmerk liegt aber eher auf Sprachnachrichten.
Als Backend habe ich mich nun für eine Serverapplikation in Java entschieden, die Clients auf Android/iOS/WindowsPhone dann in der entsprechenden Sprache.

Der Punkt, an dem ich noch rätsel ist, wie genau ich die Kommunikation zwischen der Client-App und dem Server gestalten soll. Ich würde es eigentlich schon gerne verschlüsseln, bin mir da aber nicht ganz sicher, was die eleganteste/beste Möglichkeit wäre.
Möglichkeit 1: Eigene Packets des Protokolls werden per TCP verschickt, und der Payload wird mit AES oder dergleichen verschlüsselt.

Möglichkeit 2: Ich setze mein Protokoll auf HTTPS-Basis auf und die Packets werden ohne weitere Verschlüsselung durch den "verschlüsselten HTTPS Tunnel" geschickt.​
Möglichkeit 2 wäre ja eine End-to-end Verschlüsselung, richtig? 
Aber ist es überhaupt sinnvoll ein Protokoll auf HTTP aufzubauen?

Ich freue mich auf eure Ideen und Ratschläge, bei Unklarheiten bitte nachfragen.
MFG


----------



## Tobse (27. Jun 2014)

Wenn du auf HTTPS (und damit auf HTTP) aufsetzt hast du einen ziemlichen overhead (ist schlecht für die Datenflatrate).
Du kannst aber durchaus das SSL-Protokoll nutzen, das wäre dann fast das gleiche wie die Verschlüsselung selbst zu implementieren nur eben Standardkonform.

ACHTUNG: Eine End-To-End verschlüsselung ist beides nicht, da ja nur die Verbindung verschlüsselt ist. Der Server kann die Nachrichten lesen. Jeder, der das Passwort eines Benutzers kennt kann sich als dieser ausgeben und die Nachrichten mitlesen (und auch selbst welche verschicken!).
Für eine Sichere End-To-End-Verschlüsselung brauchst du asymmetrische Kryptographie und viel Fachwissen denn schon der kleinste Fehler macht dein ganzes System undicht wie ein Sieb. Wenn du also keine fundierten Kenntnisse zu Verschlüsselung hast, eigne sie dir an, *bevor* du beginnst, Kryptographie einzusetzen. Klassen wie ein SSLSocket kannst du natürlich auch ohne Fachwissen nutzen, da dort ja Java alles kritische erledigt.


----------



## eMSch (29. Jun 2014)

Ah, danke, das hat meine Verwirrung beseitigt. Verschlüsselung soll kein Hauptkonzept der Anwendung werden, daher verschiebe ich das dann auf später.
Jedoch habe ich dann jetzt noch eine Frage: Wie verschicke und empfange ich die (Audio)Nachrichten am besten?
Ich habe zwar Erfahrung mit Streams und Server/Client Systemen in C#, jedoch habe ich mit Java noch nicht in diesem Gebiet gearbeitet, und die verschiedenen Klassen verwirren mich noch ein wenig.
Mein derzeitiger Ansatz sieht so aus:
Senden (Auf Android)

Audionachricht mit 
	
	
	
	





```
MediaRecorder
```
 aufnehmen und abspeichern
Datei in ein ByteArray umwandeln
Verbindung zum Server herstellen
Ein Byte versenden mit der Information, um was für eine Nachricht es sich handelt(Text/Voice)
Danach die Länge der Nachricht in bytes senden
Letztlich die Nachricht an sich verschicken

Mein Code sieht derzeitig so aus:

```
File f = new File(outputFile); //Aufgenommene Audiodatei
        byte[] fileArray = fileToByteArray(f);

        Socket socket = null;
        String host = "192.168.2.112";

        socket = new Socket(host, 32555);

        BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

        out.write(1);
        out.write(ByteBuffer.allocate(4).putInt(fileArray.length).array());
        out.write(fileArray);
        
        out.flush();
        out.close();
        socket.close();
```

Kann man das so machen oder gibt es da elegantere Lösungen?


----------



## Tobse (29. Jun 2014)

Das ist vom Grundsatz her mal nicht falsch. Bedenke allerdings: deine Anwendung läuft nachher auf einem Handy oder Tablet mit teilweise nur 256MB ram. So eine Audionachicht kann leicht mal 1MB groß werden. Das komplett in den RAM zu laden ist demnach auf einem Handy ziemlich schlecht. Für Genau dieses Problem benutze ich immer folgende Hilfsmethode:


```
public static void writeFile(File source, OutputStream dest)
        throws IOException
    {
        writeFile(source, dest, null);
    }

    // ProgressListener ist nur ein Hilfsinterface für Feedback zum Fortschritt (um etwa eine JProgressBar mit Infos zu einem Upload zu versorgen 
    // wenn du diese Funktionalität nicht brauchst entferne einfach die entsprechenden Zeilen und den Parameter
    public static void writeFile(File source, OutputStream dest, ProgressListener l)
        throws IOException
    {
        byte[] buffer = new byte[4096];
        long done = 0;
        long size = source.length();
        FileInputStream in = new FileInputStream(source);
        if (l != null)
        {
            l.processStarted(0, (int) size);
        }
        while (done < size)
        {
            Thread.yield();
            int read = in.read(buffer);
            if (read == -1)
            {
                break;
            }
            dest.write(buffer, 0, read);
            done += read;
            if (l != null)
            {
                l.processStateChange((int) done);
            }
        }
        if (l != null)
        {
            l.processFinished();
        }
        in.close();
    }
```


----------



## eMSch (29. Jun 2014)

Sehr sehr schön, ich glaube das ist genau das, was ich brauche. Vielen Dank dafür.
Würde dir ja auch gerne ein "Danke" geben, aber ich finde keinen Button o.ä.


----------



## Tobse (29. Jun 2014)

Es kann sein, dass man den Danke-Button erst ab einer bestimmten Zahl von Beiträgen sieht. Aber eigentlich sollte er neben dem Zitieren, unten rechts, sein  Aber wie dem auch sei - deine Botschaft kam ja bei mir an


----------

