# Software ausliefern - Aber Wie?



## RelaX (23. Dez 2013)

Guten Tag,

nun ist es bald soweit und ich befinde mich in der Endphase meiner Entwicklung.

Es handelt sich hierbei erst mal um einen Chat der neben einer Webapplikation existieren soll. D.h. die Webapplikation ermöglicht das Registrieren und sonstige Funktionen.

Mit dem Chat kann man sich dann einloggen und diesen nach Vorgabe nutzen.

Ich stelle mir hierbei allerdings einige Fragen.

Momentan läuft die Verbindung mittels Socket an ein ChatServer. Durch den login wird beim Client also Benutzername und Passwort eingetragen und an den Server gesendet. Dieser antwortet dem Client mit weiteren Instruktionen. Wie realisiere ich, bezüglich der Sicherheit, den Login am besten. Wenn ich das Passwort des Benutzers einfach über Socket im Klartext übertrage kann ich die Verschlüsselung Serverseitig tätigen und das Passwort in der Datenbank auf Korrektheit prüfen.

Das Problem liegt denke ich auf der Hand: Es wird im Klartext übertragen.

Nächste Idee:
Ich benutze eine SSL verbindung. Allerdings erfordert das einen zusätzlichen keystore der im Quelltext definiert werden muss. D.h. beim recompilieren wird dieser ja dann bekannt.

Glaub die schlechteste Idee wäre:
Beim Client das Passwort verschlüsseln. Beim recompilieren wäre die Verschlüsselungsmethode offen.

Möglichkeit? : Da Objecte Übertragen werden mittels Objectstram, ist keine Verschlüsselung notwendig? Wohl kaum.


Ich wäre wirklich dankbar wenn mir jemand helfen könnte. Mir fehlt da der korrekte Ansatz.

Vielen Dank im Vorraus.


----------



## Zettelkasten (23. Dez 2013)

Wenn der Client das Passwort verschlüsselt, kommt es eigentlich aufs selbe hinaus wie als wenn er es nicht tut:

```
1.
Client: Der User schickt ein Passwort ab
Dazwischen: Das Passwort wird abgehört
Server: Das Passwort wird gehasht um es mit dem Hash in der Datenbank zu vergleichen. Der User wird eingelogged.

-> Der Typ dazwischen schickt das selbe Passwort ab
-> Server: Das Passwort wird gehasht um es mit dem Hash in der Datenbank zu vergleichen. Der User wird eingeloggt.

2.
Client: Der User schickt ein "gehashtes Passwort" ab
Dazwischen: Das "gehashte Passwort" wird abgehört
Server: Das "gehashte Passwort" wird gehasht um es mit dem Hash in der Datenbank zu vergleichen. Der User wird eingeloggt.

-> Der Typ dazwischen schickt das selbe "gehashte Passwort" ab
-> Server: Das "gehashte Passwort" wird gehasht um es mit dem Hash in der Datenbank zu vergleichen. Der User wird eingelogged.
```
(Quelle: Passwörter verschlüsselt übertragen - Seite 2 - php.de)

Client-Seite ist nie sicher, es kann höchstems einem Angreifer das Leben schwerer machen, aber sicher ist es nie.
Benutze SSL


----------



## RelaX (23. Dez 2013)

Vielen Dank für die Info.

Also einfach eine SSLSocketverbungung verwenden? Nur wie realisiere ich das mit dem Keystore?


----------



## turtle (23. Dez 2013)

Um dieses Problem haben sich schon viele Leute Gedanken gemacht und sind zu verschiedenen Lösungen gekommen.

Neben der guten Möglichkeit SSL einzusetzen, gibt es noch andere.

Beispielsweise können sich Client und Server verständigen und sicherstellen, mit dem richtigen Gegenpart zu reden. 

Dies nennt man Authentifizierung und bedeutet, das ein Client (oder Server) beweisen muss, derjenige zu sein, die er vorgibt, wirklich zu sein. Häufig wird dies dadurch gemacht,indem ein Client eine Information dem Server präsentiert, die nur DIESER Client haben kann. Häufig ist dies die Nennung eines Passwortes.

Damit dies nicht im Klartext übertragen werden muss, gibt der Server dem Client einen Key mit, mit dem Client sein Passwort verschlüsseln kann. Weiterhin werden oft noch die Pakete zwischen Client/Server durchnummeriert um zu verhindern, das ein einfaches Replay möglich ist. So weiß der Server, das die Antwort auf Authentifizierung mit der Nummer 19 kommen muss und nicht eine andere.

Insgesamt aber eine nicht ganz triviale Sache dies umzusetzen und es ist die Frage, ob im Chat derart hoch sensible Informationen ausgetauscht werden.
Wenn du aber mehr wissen möchtest, empfehle ich sich mal mit JAAS zu beschäftigen.
Weiterhin finde ich Apache Shiro ganz interesant, das dir helfen kann.


----------



## RelaX (23. Dez 2013)

Ich versuch nur gerade ein gutes SSL-tut zu finden. Das würde das ganze eigentlich klären.

Das Problem liegt zumindest noch nicht darin das im Chat vertrauenwürdige Sachen ausgetauscht werden. Es geht um den Login. Ein Login möchte ich wirklich nicht im Klartext realisieren.

Thanks für die Links.


----------



## turtle (23. Dez 2013)

Vielleicht dies hier?


----------



## RelaX (23. Dez 2013)

Vielen Dank für die Hilfe.

Also glaub jetzt hab ich das richtig verstanden..


Ich kann mittels SSL die Nachrichten vom Server verschlüsseln.
Dann --> Ich muss ein Privaten Schlüssel zum entschlüsseln erstellen und diesem dem Client geben.
Zusätzlich bekommt der Server einen Öffentlichen Schlüssel damit dieser die Nachrichten dann verschlüsseln kann.
Folge ---> Da nur der Client diesen Schlüssel kennt kann auch nur dieser die Nachricht entschlüsseln.


Jetzt aber die Frage. Wenn ich ein Zertifikat erstelle und bei der Auslieferung diesem jedem Client gebe, dann ist der ja nicht mehr privat sondern öffentlich.

Das heißt doch das ich die Schlüssel zur Laufzeit mit einem Random-pw erstellen muss und dem Server dann den öffentlichen Schlüssel schicken muss.

Dazu finde ich leider nichts.

Wenn du mir jetzt dabei noch helfen könntest wäre das natürlich spitze.

Mfg


----------



## turtle (23. Dez 2013)

Deswegen gibt es ja auch ZWEI Schlüssel,einen privaten und einen öffentlichen...

Der private Schlüssel ist, wie der Name sagt, privat und geheim und wird nie, nie, nicht bekannt gemacht.
Der öffentliche Schlüssel ist,... nun öffentlich.

Dies geht so weit, das die Schlüssel auf Servern hinterlegt werden können, damit alle diesen lesen können.

In der Kryptographie heißen die beteiligten Personen häufig Alice und Bob.
Also nehmen wir an, Alice und Bob haben jeweils ein Schlüsselpaar erstellt.

Alice möchte eine geheime Botschaft an Bob schicken, die nur Bob lesen kann. 

Dazu nimmt Alice den Text und verschlüsselt den Text mit dem öffentlichen Schlüssel von Bob. Diesen kann Alice von einem Server im Netz abfragen (oder hat ihn bekommen). Nun kann nur Bob mit seinem privaten Schlüssel die Nachricht entschlüsseln.

Das zweite Szenario ist, wenn Alice etwas an Bob senden möchte (verschlüsselt oder nicht) und quasi die Nachricht unterschreiben möchte,so das Bob sicher ist, das die Nachricht von Alice kam und nicht von jemandem der sich als Alice ausgibt. 

Dazu schreibt Alice den Text und signiert diesen,indem aus Text ein Haswert berechnet wird und dieser mit dem privatem Schlüssel verschlüsselt wird, der Nachricht hinzugefügt wird. Bob bekommt die Nachricht und entschlüsselt die Signatur mit dem öffentlichen Schlüssel von Alice. Dann überprüft Bob, ob der Hashwert übereinstimmt mit dem berechneten Hashwert, den Bob auch errechnet hat. Stimmen beide überein, weiß Bob die Nachricht kam von Alice,sonst wurde sie verändert oder ist von einem Bösen.


----------



## RelaX (23. Dez 2013)

Ok ich glaub langsam weiß ich wie das funktionieren soll bzw. kann.

Glaub ich stehe da aufm Schlauch was das angeht.

Ich spiele mal folgendes durch.

Server ist ausgestattet mit folgendem.

ServerschlüsselPrivate(kennt NUR SERVER)
ServerschlüsselÖffentlich(Kann jeder haben bzw. erfragen)

Client meldet sich nun an Server.

Server sendet ServerschlüsselÖffentlich an Client, wenn Client diesen nicht schon hat.

Client verschlüsselt nun das Geheime mit dem ServerschlüsselÖffentlich und sendet dass dann an den Server.

Server bekommt die Nachricht und kann sie dann mit dem ServerschlüsselPrivate entschlüsseln.

Das hier ist wirklich einleuchtend und kein Problem.

Jetzt kommt aber folgendes, welches mir nicht so wirklich ersichtlich ist bei der ganzen Sache:

Ich biete nun den Client zum Download an, dann muss dieser ja schon über folgendes verfügen:

ClientSchlüsselPrivate(Kennt nur Client)
ClientschlüsselÖffentlich(Kann ja auch jeder haben)

Das muss ja irgendwo existieren bei der Auslieferung. Minimum im Quelltext.

Die Verbindung zum Server bekomme ich ja verschlüsselt hin aber umgekehrt?

Gut ich gebe dem Client einen Hashwert wie vorgeschlagen. Dennoch bringt mir das dann wenig wenn vertrauliche Daten drin stehen.

Weißte was ich meine? Stehe da vor einem Rätsel.


----------



## turtle (23. Dez 2013)

In der Tat ist der Schlüsselaustausch das am meisten unterschätzte Problem in der Kryptographie.

Nehmen wir mal an, der Server möchte zu 1000 Clients eine Nachricht schicken, die nur diese lesen können. Zunächst benötigt der Server die öffentlichen Schlüssel der 1000 Clients und muss die Nachricht 1000 mal schicken, weil der Inhalt nicht genau gleich ist.

In deinem Fall ist das deshalb schwierig, weil nur der Client ein Schlüsselpaar erstellen kann. 

Diesen öffentlichen Schlüssel müsste er dem Server mitteilen (vielleicht bei der Registrierung). Danach kennt der Server den (öffentlichen) Schlüssel des Client und kann verschlüsseln.

Das Erstellen eines Schlüsselpaares kann über ein Programm erfolgen
Pseudo-Code

```
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");  
keyPairGenerator.initialize(1024);  
KeyPair KPair = keyPairGenerator.generateKeyPair();
```


----------



## RelaX (23. Dez 2013)

Okey. Vielen Dank nochmal an dieser Stelle. Jetzt hab ich das ganze endlich raus. Ich gehe wie folgt vor.

Server:
Privater Schlüssel mittels Keystore
Offentlicher Schlüssel mittels Keystore

Client
Offentlicher Schlüssel des Servers

Somit kann jeder Client die Nachrichten verschlüsseln allerdings nicht wieder entschlüsseln. Was der Client schickt ist also absolut geheim.

Jetzt erfolgt die Anmeldung:
Client generiert mittels

```
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");  
keyPairGenerator.initialize(1024);  
KeyPair KPair = keyPairGenerator.generateKeyPair();
EasyCrypt ecPri = new EasyCrypt(rsaKeys.getPrivate(), "RSA");
EasyCrypt ecPub = new EasyCrypt(rsaKeys.getPublic(), "RSA");
```

Dieser wird zusammen mit den Logindaten dem Server mitgeteilt.

Wunderbar!!! Genau das hab ich gebraucht.

Vielen Dank.


----------

