Performant Files senden/empfangen

Ich bin auf der Suche nach einem Protokoll mit dem man Daten schnell u. wenn möglich auch sicher übers Netzwerk zu senden.

Das ganze soll neben Java SE auch auf Android laufen. Im Moment kommen in Frage:
[ol]
[li]Plain TCP-Socket und das File streamen.
[/li][li]FTP (Pro: Gute Unterstützung für Android/JavaSE. Die Frage ist ob’s da nicht schnellere Lösungen gibt.)
[/li][li]SCP (Pro: schnell, sicher. Con: Auf den erste Blick nichts brauchbares für Android gefunden.)
[/li][li]SFTP (Pro: Gibt Libs für Java/Android. Con: ?)
[/li][li]HTTP (Pro: Libs für Java/Android. Con: Protokol mit Bloat?)
[/li][/ol]

Genial wäre es, wenn die Library von alleine Verbindungsabbrüche u. Retries handeln könnte.

Habt ihr Empfehlungen für so etwas?

Wenn Sparsamkeit das Maß ist, kommt Verschlüsselung nicht in Frage. Sie trägt mit Abstand am meisten zu einem Overhead bei. Habe mal Messungen zum Vergleich von IPSec, SCP und unverschlüsselt gemacht und bin auf ca. 20% mehr Datenvolumen bei den verschlüsselten Übertragungen gekommen. Denke aber, dass das heut zu Tage eh nur noch ein Problem ist, wenn jemand per GSM surft oder die Geschwindigkeit vom Provider gedrosselt wurde.

Vor weiteren Details erst mal die Frage, ob Du damit leben kannst.

Sparsamkeit ist relativ. Die Prozessorleistung ist mir egal. Und ja, ich kann damit leben. Vor allem wenn’s 'ne Lib gibt die mir viel Arbeit abnimmt :slight_smile:

Wäre zumindest für den Prototypen absolut in Ordnung.

Heisst SFTP nicht SecuredFileTransferProtokoll? Ich würd’s damit machen.

Ich meinte schon den Overhead bei den übertragenen Daten. Nach Prozessorbelastung hattest Du in Deinem ersten Post ja nicht gefragt. Ich interpretiere Deine Antwort dennoch so, dass auch das Mehr an übertragenen Daten Dich nicht stört. Dann würde ich https als erste Wahl nehmen. Http(s) ist inzwischen das Schweizer Taschenmesser der Protokolle. Es gibt dafür gute Libs und es ist auch in den meisten Umgebungen (Firewalls etc.) freigegeben. Wie bei allen sicheren Protokollen muss man sich hier mit Zertifikaten/Schlüsseln auseinandersetzen. Am besten ist hier eine PKI. Aber auch mit vorimportierten selbst signierten Zertifikaten kann man arbeiten.

Dann hast du aber sehr, sehr kleine Dateien übertragen. Denn die Verschlüsselung vergrößert das Datenvolumen nicht, sondern nur der Handshake und die „Dateiinitialisierung“. Und die „Dateiinitialisierung“ hat man bei jedem Protokoll, egal ob verschlüsselt oder nicht.

Also den besten Datendurchsatz hat man wohl mit 'ner Permanentverbindung zwischen 2 Sockets, weil die Authentifizierung nur einmal beim Verbindungsaufbau stattfindet. Darauf könnte man ja theoretich sein eigenes Protokoll aufsetzen und bei Bedarf die SocketBuffer vor dem Senden ver- und nach dem Empfang entschlüsseln. Das Ganze evtl. noch in einen Zip-Stream geschachtelt, dann wirds möglicherweise auch kürzer. Dann evtl. noch PacketHeader, dass man zwischen Nutz- und Verwaltungsdaten unterscheiden kann und fertig ist das Protokoll.

Bei einer möglichen Verschlüsselung dann unbedingt dran denken, die Daten erst zu komprimieren und dann erst zu verschlüsseln und nicht umgekehrt.

Habe nach Deinem Hinweis noch mal einen scp-Transfer auf einen Server im Internet gemacht. Dateigröße 500Mb. Vorher und nachher mit ifconfig die Rx-Bytes ausgegeben. Ergebnis: 550MB. Das sind dann nur noch 10%. ABER, bei dem Overhead ist natürlich auch TCP/IP und evtl sogar Netzwerk dabei. Das hatte ich nicht berücksichtigt. Für das Aufsetzen eines IPSec-VPN war mir der Aufwand zu groß. Würde aber da von dem gleichen Denkfehler ausgehen. Insofern muss ich meine Aussage von weiter oben zurück nehmen.

Ich hab im Moment Apache MINA im Auge. Wenn ich mal dazu komme die Android-Kompatibilität zu testen wird’s entweder SCP oder FTP. Je nachdem ob das dann tatsächlich so langsam ist oder nicht. Denke aber dass das per SCP im WLAN vernünftig laufen sollte.

Ich bin ja leider sehr paranoid weswegen ich einen Open-Source-Ersatz für das Files-Versenden-Feature von AirDroid bauen möchte.

scp und sftp sind beide ssh-basiert. Wenn du also eine Funktionalität benötigst, um Verzeichnisinhalte zu listen, solltest du sftp nehmen.

sftp ist übrigens nicht mit ftps zu verwechseln, welches du im Startpost nicht aufgeführt hast. ftps ist ftp über SSL/TLS und entsprechend nicht ssh-basiert.

pseudo-krypto-intellektuell gefragt:
gibt es da auch keinen Angriffspunkt auf die Verschlüsselung, weil bestimmte Bytes des Zips, etwa am Anfang, schon bekannt sind?
http://ig.cs.tu-berlin.de/oldstatic/ap/rg/002/glossar/k-terms/klartextangriff.html

(Link zählt übrigens für Godwin’s law :wink: )

Wenn man sftp / ftps oder einen “Rohen” Stream mit einem eigenen Protokoll per AES oder Blowfish verschlüsselt, dann ist das kein Problem. Die “gängigen” Algorithmen sind immun gegen Known-Plaintext / Chosen-Plaintext-Angriffe.
Wenn man eine Stromchiffre oder einen Blockcipher benutzt um den Datenstrom zu verschlüsseln, sollte man den Schlüssel entweder per Diffie-Hellman-Key-Exchange oder per asymmetrischer Verschlüsselung (z. B. RSA) austauschen.

Achtung: AES ist ein Stromchiffre. Deshalb muss man hier, wie von @cmrudolph erwähnt, den Schlüssel per z.B. RSA austauschen.

Apache MINA bietet nur FTP oder SSH/SCP an. Ich probier mal ob ich das ganze per SCP zum Laufen bekomme und wenn das nicht funktioniert schau ich weiter zu FTP. Hoffentlich funktioniert eines von den beiden, denn das schöne an dem Apache MINA Projekt ist, dass es auf Performance ausgelegt ist, sowohl Client wie auch Server Libs enthält und gleichzeitig für den Programmierer relativ leicht zu verwenden ist (jedenfalls das, was ich in der Doku gesehen habe…).

Apache MINA läuft mit Android prima. Mein SIMON baut da ja auch drauf auf und mit Android gabs bis dato keine größeren Probleme (Probleme gab es eigtl nur mit der Serialiserung die bei manchen JRE Klassen auf DesktopVM und DalvikVM anders gehandhabt wird).

SIMON hat übrigens neben dem RPC Mechanismus auch einen sogenannten RawChannel, mit dem man recht einfach Rohdaten versenden und empfangen kann. Das ganze natürlich mit SSL Unterstützung sowie parallelen Transfers über eine einzelne Socket-Verbindung. Natürlich gibt’s auch etwas Protokoll-Overhead. Aber der ist je nach Blockgröße mit der man schreibt zu vernachlässigen.

Nee, AES ist eine Blockchiffre (d. h. erstmal für Streamverschlüsselung ungeeignet, mit Puffer ist das aber kein Problem).
Was du meinst ist, dass AES ein symmetrisches Verschlüsselungsverfahren ist, was bedeutet, dass beide Kommunikationspartner den selben Schlüssel haben müssen.

Nein, das mein ich nicht. Ich hab einfach was falsches behauptet :slight_smile:

Du hast recht, das ist ein Blockchiffre. Auf den CC2510er Boards von TI war der Buffer in den Hardware-Modulen deswegen hab’ ich das verwechselt. Die Dinger hatten nämlich extra einen Crypto-Chip damit das schnell geht. Das hab ich mir seitdem falsch gemerkt.

Edit:/
SIMON wäre auch eine Idee. Ich glaub ich bau’s mit dem. Danke für den Hinweis

Würde mich über Feedback freuen.
In 1.2.0-SNAPSHOT gibt’s seit einiger Zeit ein extra FIle-Transfer-Feature: http://dev.root1.de/projects/simon/wiki/FileTransmit_120

1.2.0-SNAPSHOT ist soweit schon stable, aber noch nicht ganz feature-complete.