Android platzsparende Codierung verschlüsselter Texte in einer URI

Tecwan

Aktives Mitglied
Hallo,

ich möchte mit meiner App Daten mit einem Server austauschen, die verschlüsselt auf diesem
abgelegt werden. Auch die Abfrage soll verschlüsselt erfolgen.
Für die Abfrage möchte ich ein PHP-Skript benutzen, das per GET eine verschlüsselte Anweisung
erhält, die es entschlüsselt und die darin enthaltenen Anweisungen ausführt und Daten zurückliefert.
POST oder Sessions lohnen sich nicht, da zumeist nur eine einzige (teils kombinierte) Anfrage erfolgen
soll (und Verbindungen der Art Frage-Antwort vermutlich schneller übertragen werden als solche
der Art Frage-Rückfrage-Rückantwort-Antwort).

Zum Codieren möchte ich Rijandael-128 (AES) verwenden, das ByteArrays verwendet. Um diese
Binärdaten zu übertragen, müssen sie (zumindest auf dem Hinweg zum Skript) noch codiert werden.

HEX-encoding lässt allerdings die Datenmenge auf das Doppelte anschwellen:
Code:
Klartext -(Rijndael-128-encrypt)-> byteArray -(HEXencode)-> HEXAcodedText

Auf der Suche nach Alternativen bin ich auf die Codierung mit BASE64 gestoßen, die den
verschlüsselten Text nur um ca. ein Drittel vergrößert (+ x% für das notwendige URLencode):
Code:
Klartext -(Rijndael-128-encrypt)-> byteArray -(BASE64encode)-> BASE64codedText -(URLencode)-> urlBASE64codedText

Gibt es geeignetere Alternativen?
 

Tecwan

Aktives Mitglied
URLencoding von Klartext ist platzsparend, weil überwiegend Zeichen enthalten sind, die nicht
maskiert werden müssen. Daher ist diese Methode für Klartext besser als hex oder base64.

Ich sende aber AES-Ciphertext, also im Grunde Binärdaten.
Die kann ich zwar als byteArray mit
Code:
new String(encryptedByteArray,"UTF-8")
umwandeln,
aber das Ergebnis lässt sich nicht platzsparend urlEncoden:
Bei angenommener Gleichverteilung der Bytewerte müssten außer den (meisten) ASCII Zeichen
alle anderen Zeichen maskiert werden, und das jeweils mit drei Bytes. Nimmt man an, von den
256 möglichen Zeichen kämen 64 unmaskiert durch, würden aus je 100 Bytes dann 250,
das ist noch schlimmer als hex.

Für Klartext reicht URLencode, bei Binärdaten muss ich entweder hexen oder aber einen
sparsameren Code nehmen und URLencoden.
 

dzim

Top Contributor
Und die Daten als Post zu schicken, ist keine Alternative? Ich finde ja so hässliche und lange URLs immer doof :)
 

Tecwan

Aktives Mitglied
Hat POST nicht gegenüber GET einen größeren Headeraufwand?

Wenn nicht, ist POST natürlich erste Wahl - Binärdaten erlaubt.
 

dzim

Top Contributor
Hm... Ehrlich gesagt weiß ich das nicht. Wir haben aber mal eine Tablet-App für einen Kunden gebaut, bei der die gesamte Synchronisation von lokaler (Tablet) und zentraler (Server) Datenbank über Pseudo-ReST (sprich: alles via POST) gemacht haben. Einen sprürbaren Einfluss hatte das nicht. Eher als nachteilig hat sich die hohe Abstraktion für die Android-DB erwiesen. Das kann zwar an mangeldem Know-How gelegen haben (meine erste Android-App überhaupt) wäre ab einfach mit Plain-SQL auf der SQLite-DB zu beheben gewesen (was nicht notwendig war, da die Lebenszeit der fertigen App eh nur auf 2 Monate begrenzt war - das hat den Aufwand nicht mehr gerechtfertigt).

Probier es einfach mal aus - kannst uns ja mal deinen Erfahrungsbericht geben :)
 

Tecwan

Aktives Mitglied
Ich habs jetzt mal per POST versucht, bin aber nicht sehr weit gekommen.
Die Header scheinen sich nicht wesentlich zu unterscheiden; was beim GET im URI steht, steht beim
POST im Header (wenn keine Binärdaten).

Aber das wird ja von Android-Seite 'unsichtbar' erledigt, darum brauche ich mich wohl nicht zu
kümmern.
Dachte ich. Fatalerweise: denn Client und Server handeln intern bei Binärdatenübertragung vlt.
wieder BASE64 aus.

Praktisch beginnt die Umsetzung mit der Klippe, dass im Browser die eingegebenen Daten sowohl
bei GET als auch bei POST im URI oder eben mit dem POST-Header als name-value-Paare übermittelt
werden. Bei Ascii kein Problem, zusätzlich wird quasi automatisch urlendoded.
Das will ich nicht, ich möchte ja nur ein verschlüsseltes Packet zum Server senden, da brauche ich
eben keinen name-value-Overhead, und erst recht kein urlencode.

Bei File-Uploads zB. ist das ja auch nicht nötig, bzw. möglich.
Auf Android-Seite kann ich den HTTP-Request explizit mit einem byteArray losschicken.
Aber wie empfange ich das auf PHP-Seite?
Code:
$request = $_POST['name'];
scheitert natürlich daran, dass 'name' nicht existiert.
Der Server erstellt stattdessen ein temporäres File, auf das ich dann zugreifen kann mit
Code:
$request = array(readfile("php://input"));

Mittlerweile habe ich diesen Weg aufgegeben, und zwar aus 2 Gründen:
- meine eigene Unzulänglichkeiten mit PHP:
$request sollte eigentlich auch ein ByteArray sein, ich schaffe es aber nicht, dieses geeignet an
meine decrypt-Funktion weiter zu reichen. (Typen in PHP...)
- die starke Vermutung, dass der Binärdatenstrom sowieso wieder BASE64-codiert übertragen wird.

Daraus folgt, dass ich außer dem Vorteil, im Datenvolumen meiner Binärdaten nicht beschränkt zu
werden, keinen Vorteil habe, da die Übertragung doch wieder BASE64-encoded erfolgt.


Fazit für mich:
Ich bleibe beim GET und investiere meine Zeit eher darin, die Redundanzen in den Daten zu vermindern.
 

Tecwan

Aktives Mitglied
Na, wer weiß?

Wir brauchen doch bloß ein paar neue internationale Normen für die Datenübertragung im Netz, gefolgt
vom Austausch sämtlicher Hardware, die immer noch nur mit 7-bit ASCII sicher kommunizieren kann, und
dann...

Danke jedenfalls dafür, dass ich jetzt klarer sehe.
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben