Hallo,
ich möchte eine Webapp absichern, so dass niemand gezielt sensible Daten
abfragen kann.
Allerdings müssen pro Client Anfragen mit hoher Frequenz beantwortet
werden, und alle Pakete per SSL zu verschlüsseln würde die Webapp zu
sehr ausbremsen.
Meine Hoffnung ist, dass es eine Möglichkeit gibt, nur die
Authentifizierung über SSL abzuwickeln, den späteren Datenverkehr aber
unverschlüsselt und trotzdem sicher zu implementieren. Mir fehlt es
etwas an Vorstellungskraft, mir hierfür sichere und effiziente Konzepte
auszudenken. Eine Idee wäre folgende:
Während der Authentifizierung schickt der Server dem Client
verschlüsselt einige 100000 Keys, die der Client später in der selben
Reihenfolge Stück für Stück bei jedem Request mitschickt. Klar, das
verhindert nicht, dass jemand, der den http-Verkehr mithören kann, die
empfangenen Daten mitliest. Jedoch sollte es dritten trotzdem unmöglich
sein, gezielte Anfragen an den Server zu schicken. Oder habe ich etwas
übersehen?
Wahrscheinlich ist meine Idee entweder unbrauchbar, oder etwas ähnliches
ist längst fertig implementiert ohne dass ich davon weiß. Könnt ihr mir
Stichworte nennen, die mir sinnvolle Lösungen liefern?
Danke
Frank
Nein, das haben schon viele Leute geglaubt. Danach kann jemand, zum
Beispiel das Cookie zur Authentifizierung nutzen, oder gar die Daten
einfach mitsniffen oder verändern. Oder man kann Javascript rein
schleusen was einfach den ganzen Code den Du vorher verschlüsselt
übertragen hast auf einmal an einen Drittserver schickt, usw.
Übrigens, wenn Du viele kleine Datenpakete übertragen willst, dann ist
wahrscheinlich Websocket das, was Du nutzen möchtest. Da kannst Du viele
kleine Objekte über eine Verbindung übertragen.
Kann es sein das bei dir https nur so "langsam" ist, weil du immer eine
neue Verbindung aufbaust? Mit http 1.1 kann man die Verbindung offen
lassen, damit braucht man nur einmal den Schlüsselaustausch.
Die eigentliche Verschlüsselung sollte fast keine CPU zeit verbrauchen.
Alternative über https einfach eine AES Schlüssel austauschen, und dann
die Daten mit http und verschlüsselt mit AES übertragen.
Christian Berger schrieb:> Danach kann jemand, zum> Beispiel das Cookie zur Authentifizierung nutzen, oder gar die Daten> einfach mitsniffen oder verändern.
Das ist nicht richtig. Der Client erhält zu Anfang auf sicherem Weg
ausreichend Einweg-Keys.
Der Server weiß jeweils, welchen Key er als Nächstes mit der Anfrage
erwartet.
Was hilft es jemandem, mitzulesen? Dass er evtl. Daten abfangen kann,
ist in meinem Fall nicht kritisch. Er darf nur nicht in der Lage sein,
selbst gezielte Anfragen zu schicken.
Frank S. schrieb:> Das ist nicht richtig. Der Client erhält zu Anfang auf sicherem Weg> ausreichend Einweg-Keys.
aber wozu der aufwand? Reicht nicht ein key?
klar könnte man darüber nachdenken, nach ein paar Megabyte eine neue
Schlüssel zu verwenden, aber doch nicht bei jeden Transfer.
Aber wie schon oben geschrieben, wenn man bei https die Verbindung offen
lässt sollte das auch ohne große CPU last gehen.
Peter II schrieb:> Kann es sein das bei dir https nur so "langsam" ist, weil du immer eine> neue Verbindung aufbaust? Mit http 1.1 kann man die Verbindung offen> lassen, damit braucht man nur einmal den Schlüsselaustausch.
ja, so mache ich es schon
> Die eigentliche Verschlüsselung sollte fast keine CPU zeit verbrauchen.
Beim Server nicht. Aber lauf Profile verschwenden langsamere Clients
über 99% ihrer CPU an die Entschlüsselung.
> Alternative über https einfach eine AES Schlüssel austauschen, und dann> die Daten mit http und verschlüsselt mit AES übertragen.
Bringt überhaupt nichts, da der Aufwand für die Entschlüsselung derselbe
ist.
Frank S. schrieb:> Beim Server nicht. Aber lauf Profile verschwenden langsamere Clients> über 99% ihrer CPU an die Entschlüsselung.
was haben denn die Clients für CPUs?
Peter II schrieb:> aber wozu der aufwand? Reicht nicht ein key?>> klar könnte man darüber nachdenken, nach ein paar Megabyte eine neue> Schlüssel zu verwenden, aber doch nicht bei jeden Transfer.
Ein Key kann bei der ersten Anfrage mitgeschnitten werden. Danach kann
ein Eindringling seine eigene Anfrage mit demselben Key formulieren,
wenn er weiterhin gültig ist.
Hast du dich schon mal mit Verschlüsselung beschäftigt?
Frank S. schrieb:> Beim Server nicht. Aber lauf Profile verschwenden langsamere Clients> über 99% ihrer CPU an die Entschlüsselung.
Wenn du eine Internet-Anbindung hast, die schneller ist als ein normaler
Allerweltsprozessor einen AES Stream entschlüsseln kann, dann trifft
dich mein ganz aufrichtiger Neid.
Frank S. schrieb:> Ein Key kann bei der ersten Anfrage mitgeschnitten werden.
wie soll das bei https gehen?
> Hast du dich schon mal mit Verschlüsselung beschäftigt?
ja
Verschlüsselung und Authentifikation sind verschiedene Dinge.
Peter II schrieb:> Frank S. schrieb:>> Ein Key kann bei der ersten Anfrage mitgeschnitten werden.> wie soll das bei https gehen?
Außer der Authentifizierung und der Übermittlung der Einwegschlüssel
soll die Kommunikation OHNE https laufen. Das war der Kern meiner Frage.
Du könntest den Client die Nachrichten jeweils signieren lassen,
bräuchtest dafür aber eine laufende Nummer oder eine Referenz auf die
vorhergehende Nachricht um Replay-Attacken zu verhindern. Das ist
insofern nervig das immer nur eine Anfrage parallel gestartet werden
kann, nicht ganz eindeutig ist was bei verlorenen Requests passiert, und
die Server sich auch immer merken müssen was denn als nächstes kommen
darf.
Langlebige Verbindungen sind wie schon angesprochen vermutlich sehr
hilfreich, der initiale Schlüsseltausch bei HTTPS ist teuer, die
eigentliche Übertragung danach nicht mehr.
Frank S. schrieb:> Peter II schrieb:>> Frank S. schrieb:>>> Ein Key kann bei der ersten Anfrage mitgeschnitten werden.>> wie soll das bei https gehen?>> Außer der Authentifizierung und der Übermittlung der Einwegschlüssel> soll die Kommunikation OHNE https laufen. Das war der Kern meiner Frage.
Richtig. Aber die wozu Einwegschlüssel?
Da der Schlüssel eh nicht übertragen wird, kann man ihn auch mehrfach
verwenden zum verschlüsseln der Daten.
Um gefälschte Daten zu erkennen schickt man einen laufenden Zähler und
eine Prüfziffer.
Aber wie auch schon von A. K. angemerkt, es kann fast nicht sein das
eine symmetrische Verschlüsselung so viel CPU zeit braucht.
ein ARM mit 50Mhz soll schon über 2Mbyte/s verarbeiten können.
Peter II schrieb:> ein ARM mit 50Mhz soll schon über 2Mbyte/s verarbeiten können.
Fand grad einen Test von 2011, demgemäss Truecrypt auf einem Sandy
Bridge Prozessor 1,5GB/s durchsetzt, wenn der AES Befehlssatz zum Tragen
kommt. Ohne den waren es immerhin noch 277MB/s (Bytes pro Sekunde).
Ok, bei einem SSL Stream wirds sicherlich weniger, weil weniger
aggressiv optimiert und parallelisiert, aber es sollte sogar für
schnellstes TV-Kabel noch ausreichen. Da macht eher der Server schlapp,
denn wer denkt, ein Server wäre immer das Schnellste unter der Sonne,
der irrt oft. Die sind im Mittel älter als die Desktops, die drauf
zugreifen.
Peter II schrieb:> Richtig. Aber die wozu Einwegschlüssel?>> Da der Schlüssel eh nicht übertragen wird, kann man ihn auch mehrfach> verwenden zum verschlüsseln der Daten.
Sorry, aber das wird mir jetzt zu blöd. Man sollte sich aus Diskussionen
heraushalten, wenn man nur Bahnhof versteht.
Lol, sagt der Richtige. Niemand hat davon geredet dass du einen Key im
klartext rumschicken sollst den man "mitschneiden" könnte, also erklär
doch das Angriffsszenario mal genauer dass er nicht versteht.
Frank S. schrieb:> Allerdings müssen pro Client Anfragen mit hoher Frequenz beantwortet> werden, und alle Pakete per SSL zu verschlüsseln würde die Webapp zu> sehr ausbremsen.
SSL braucht weniger CPU als du denkst.
Frank S. schrieb:> Sorry, aber das wird mir jetzt zu blöd. Man sollte sich aus Diskussionen> heraushalten, wenn man nur Bahnhof versteht.
Der einzige der nur Bahnhof versteht bist Du. Entschuldige, aber die
Idee mit tausenden Einwegschlüsseln ist absoluter Blödsinn.
Nimm https und gut ist.
Wie schon mehr als einmal gesagt:
- bei https ist der initiale Schlüsselaustausch teuer
- danach ist es eine normale, symmetrische Verschlüsselung - das kriegst
du mit deinen tausenden Einwegschlüsseln auch nicht schneller hin - im
Gegenteil. Wo sollen die gespeichert werden? Was machst du wenn mal ein
Paket verloren geht? Du hast das nicht zu ende gedacht...
Ich würde das Problem so sehen: Nur authentifizierte Clients dürfen
Anfragen stellen. Die Anfrage und Antwort selbst dürfen aber mitgelesen
werden.
Mal ein paar unreine Gedanken
--
Frage: Wenn ein nicht autorisierter Client eine bereits mitgelesene
Anfrage schickt, darf er dann die damalige Antwort (mit den damaligen
Daten) erhalten? Dies dürfte keine Geheimnisse verletzen. Problematisch
wäre es, wenn er eine neue Antwort mit aktuellen Daten erhält.
Dann könnte man sich für eine Zeit die bereits beantworteten Anfragen
merken, und vielleicht die selbe Antwort oder einen Fehler zurückgeben.
Dann muss man natürlich garantieren, dass sich der Client entweder nach
einer Zeit neu authorisiert, oder aber jede Anfrage mit einem
(verschlüsselten) Zeitstempel versehen, so dass sie nur eine gewisse
Zeit erneut gestellt werden darf.
--
Zurück zu den 100000 Keys: Müssen die alle in der richtigen Reihefolge
geschickt werden? Ansonsten könnten die auch gruppiert werden, und man
muss nur einen Key aus der Gruppe mitschicken. Das könnte das Problem
mit dem vorlorenen Packet lösen.
Ansonsten könnte man auch einen Zähler mitschicken, so dass der
Antworter ein verlorenes Packet erkennt; danach könnte er einfach eine
neue Authorisierung veranlassen.
--
Anstelle der 100000 Keys könnte man auch auf beiden Seiten einen
Pseudozufallszahlen-Generator verwenden, dessen Anfangswert bei der
Authorisierung ausgetauscht wird.
---
Eine weitere Idee wäre, anhand a) der Anfrage (z.B. durch einen Hash),
b) einem aktuellen Zeitstempel und c) einem gemeisamen Geheimnis aus der
Authentifizierung einen Token zu generieren, der mit der Anfrage
mitgeschickt wird. Dann braucht nicht mehr die ganze Nachricht
entschlüsselt zu werden, sondern nur noch der Hashwert.
Wenn es nicht ganz so kritisch ist, könnte man sich vielleicht sogar auf
einen Teil der Nachricht beschränken, aus dem der Hash berechnet wird.
Die Wahl des Teils könnte vom gemeinsamen Geheimnis abhängen.
Zeitkritisch ist natürlich die Erzeugung des Hashwertes.
>Allerdings müssen pro Client Anfragen mit hoher Frequenz beantwortet
werden, und alle Pakete per SSL zu verschlüsseln würde die Webapp zu
sehr ausbremsen.
Nee. Muss ein Client nicht. Ein Client hat alle Zeit der Welt. Die
Telephonverbindung kann auch weniger gut wie ideal sein.
Allenfalls muss man sich bei einem Server Gedanken ueber die Last
machen.
Frank S. schrieb:>> Die eigentliche Verschlüsselung sollte fast keine CPU zeit verbrauchen.>> Beim Server nicht. Aber lauf Profile verschwenden langsamere Clients> über 99% ihrer CPU an die Entschlüsselung.
Falls das Apache ist: Setz mal den KeepAliveTimeout für den
entsprechenden VHost hoch. Der Default von 5 Sekunden bedeutet in der
Praxis das für jeden Klick vom Nutzer ein neuer Verbindungsaufbau mit
Schlüsselaustasch (teuer, IMO auch auf dem Server) nötig ist. Ich würde
so 30-60 Sekunden Timeout vorschlagen und dann mal nach der Last auf dem
Server schauen.
Falls das nicht Apache ist: Andere Server sollten analoge Einstellungen
kennen.
Was anderes als https ist ziemlicher Mist IMHO und würde mobile Clients
noch viel stärker ausbremsen, insbesondere wenn man unautorisierte
Veränderung von Daten erkennen möchte.
Jetzt Nicht schrieb:>>Allerdings müssen pro Client Anfragen mit hoher Frequenz> beantwortet> werden, und alle Pakete per SSL zu verschlüsseln würde die Webapp zu> sehr ausbremsen.>> Nee. Muss ein Client nicht. Ein Client hat alle Zeit der Welt. Die
Schwachsinn. Zeitkritische Daten müssen nun einmal mit einer bestimmten
Frequenz abgespielt werden. Behauptest du das auch von deinem CD-Player,
dass er alle Zeit der Welt hat, wenn er die Musik nur mit 1k Samples/s
wiedergibt, obwohl sie mit 44kHz aufgezeichnet wurde?
> Telephonverbindung kann auch weniger gut wie ideal sein.
Dein Deutsch kann auch weniger wie ideal sein. Das entschuldigt trotzdem
keine sinnfreien Behauptungen.
Hm, wo treten eigentlich die größeren Probleme auf:
Beim Verschlüsseln der Anfrage auf dem Client, den Entschlüsseln der
Antrage auf dem Server, den Verschlüsseln der Antwort auf dem Server
oder dem Entschlüsseln der Antwort auf dem Client?
Ich tippe mal, dass es das Entschlüsseln auf dem Client ist.
Als Szenario für ein Gedankenexperiment konstruiere ich mal eine
Multimedia-Plattform, die persönliche Videostreams an Settop-Boxen von
Kunden mit langsamer aber handelsüblicher Hardware verteilt.
Über http kann man auch verschlüsselte Binär-Daten übertragen.
Wie wäre es mit folgender Kombination:
Bei Beginn und in zeitlichen Abständen kommunizieren Client und Server
über sicheres HTTPS und tauschen Zweit-Schlüssel aus. Die eigentliche
Massendaten werden über einen einfacheren, performateren Algorithmus mit
diesen Zweitschlüsseln verschlüsselt, oder vielleicht auch nur
verschleiert.
Achim Hensel schrieb:> Ich tippe mal, dass es das Entschlüsseln auf dem Client ist.
Worauf gründet diese Vermutung? Gängige symmetrische Verfahren wie AES
sind auch hinsichtlich der Performance einigermassen symmetrisch.
Achim Hensel schrieb:> Bei Beginn und in zeitlichen Abständen kommunizieren Client und Server> über sicheres HTTPS und tauschen Zweit-Schlüssel aus. Die eigentliche> Massendaten werden über einen einfacheren, performateren Algorithmus mit> diesen Zweitschlüsseln verschlüsselt, oder vielleicht auch nur> verschleiert.
Gratuliere! Du hast soeben HTTPS, SSL/TLS und IPSEC erfunden. ;-)
Genau das passiert da nämlich. Ein aufwändiges asymmetrisches Verfahren
wird verwendet, um den Schlüssel eines performanten symmetrischen
Verfahrens zu vereinbaren. Der bei längeren Verbindungen ab und zu
ausgetauscht wird.
Weshalb hier auch schon erwähnt wurde, dass der ganze Trick nur darin
besteht, die SSL Verbindung (HTTPS ist HTTP über SSL) deutlich länger
offen zu halten.
Auch PGP arbeitet nach diesem Schema. Das aufwändige Verfahren überträgt
nur den zufällig erzeugten Schlüssel des performanten symmetrischen
Verfahrens für den eigentlichen Inhalt.
Sorry. Wenn ich eine CD, resp Musik von einem Server downloade, kann ich
nicht davon ausgehen, dass das in Echtzeit geschieht.
Das Internet ist redundant designt, es muss auch bei suboptimalen
Bedingungen laufen. Falls man hohen Durchsatz will, muss man sich eben
von TCP verabschieden und mit UDP arbeiten, wo auch mal was verloren
gehen kann. Wie Skype, da ruckelt es manchmal. Skype ist uebrigens auch
verschluesselt.
Jetzt Nicht schrieb:> Das Internet ist redundant designt, es muss auch bei suboptimalen> Bedingungen laufen. Falls man hohen Durchsatz will, muss man sich eben> von TCP verabschieden und mit UDP arbeiten, wo auch mal was verloren> gehen kann. Wie Skype, da ruckelt es manchmal. Skype ist uebrigens auch> verschluesselt.
wenn aber alle Daten wichtig sind und nichts verloren gehen darf, dann
bringt eine UDP auch nichts.
Sprach/Video-Daten in Live-Übertragung arbeiten eigentlich immer per
UDP. Mit Durchsatz hat das aber überhaupts nichts zu tun, sondern mit
der Art des übertragenen Inhalts. Es ergibt schlicht keinen Sinn,
verlorene Daten zu wiederholen. Der Versuch würde das Problem nur
vergrössen.
Hohen Durchsatz erreicht man auch mit TCP. Ein Beispiel dafür ist NFS,
das früher per UDP arbeitete, mittlerweile aber überwiegend per TCP
arbeitet.