Autor |
Beitrag |
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 06.04.07 23:33
Moin!
BenBE hat folgendes geschrieben: | Protokoll-ID und Version über OI einstellbar (Sonst wären ja theoretisch alle Anwendungen miteinander kompatibel ) |
Du hast den Transportprotokoll-Header in den "falschen Hals" gekriegt, BenBE. Es geht nämlich genau darum: die Komponente soll mit anderen Kompos, egal wo kompiliert, "reden" können. Es ist also ein Komponenten-Standard, der da etabliert werden soll. Was du möchtest, muss erst im Anwendungsprotokoll definiert und behandelt werden: Anwendungsidentifikation und Versionierung!
BenBE hat folgendes geschrieben: | OnEncryptData \ OnDecryptData pro Datenblock (feste größe einstellbar \ an Framegrenzen) decodierbar (um z.B. teilweise verschlüsselte Kommunikation zu realisieren) |
Ja, da hatte ich auch schon drüber nachgedacht... aber den Gedanken wieder verworfen, weil mir das so schnell so komplex wurde (das interne Caching ist da nicht ganz unproblematisch), dass ich mir nicht mehr sicher war, ob ich die Kompo noch 2007 veröffentlicht kriege... Fazit: mal sehen, vielleicht mal, wenn ich vieeel Zeit und Langeweile habe... Ansatz: definiere für verschlüsselte Frames entsprechende Token, dann geht das auch so.
BenBE hat folgendes geschrieben: | Einstellbare adaptive Framegrößen-Übertragung (um ähnlich RFC2440 die für die Größenangabe benötigten Informationen zu reduzieren) |
Hehe, du gibst aber auch nicht auf wenn du das unbedingt haben willst, dann mach dir mal Gedanken, wie dann das Transportprotokoll dafür aussehen soll und schick mir eine PN mit dem Vorschlag... (das ist nicht soo einfach, wie du dir das Vorstellst) Abgesehen davon: was willst du denn da aktuell einsparen? 1 Byte, wenn die Datenmenge < 255 Zeichen im Frame ist? Was soll das bringen?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 12.04.07 22:25
Moin!
Ein weiteres (Demo-)Projekt mit den TNBFPA-Komponenten: Mal-FileTransfer-Chat
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 07.05.07 22:03
Moin!
Hier das nächste Tutorial aus meiner Netzwerk-Reihe: Multiplayer-TicTacToe
Viel Erfolg damit,
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 03.06.07 18:27
Moin!
Neue Version (v1.04, Bugfixes und neue Funktionen), Details im ersten Beitrag.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.06.07 14:20
Moin!
Neue Version 1.05 (FIX in der Ereignisreihenfolge des TNBFPAServer), Details im ersten Beitrag.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 23.06.07 20:27
Moin!
Neue Komponenten- (v1.06) und Doku-Versionen (v1.04), Details - wie immer - im ersten Beitrag.
//EDIT: Update der Komponente auf v1.07 (Bugfix)
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Do 05.07.07 10:21
Hallo Narses,
ich habe mit deinen Komponenten einen Chat gebastelt und wollte nun die Verschlüsselungsereignisse benutzen. Dazu habe ich eine RCx-Unit von negaH benutzt. Das ganze sieht jetzt auf beiden Seiten(Client und Server) so aus: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TMainForm.ClientEncryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); var ARCx: TRCxContext; begin RCxInit(ARCx,'<Passwort>'); RCxEncode(ARCx,Buffer,Buffer,Size); RCxDone(ARCx); end;
procedure TMainForm.ClientDecryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); var ARCx: TRCxContext; begin RCxInit(ARCx,'<Passwort>'); RCxDecode(ARCx,Buffer,Buffer,Size); RCxDone(ARCx); end; | Allerdings kommen manchmal 2 gesendete Pakete als ein Paket beim Empfänger an, wodurch die Entschlüsselung nicht funktioniert.
Beispiel:
Server sendet 1B4BA8037D0EF2119A8E9FE15BF94E2B3EEBB6EA und 53E3DD9B62D668F41801ED0B8C336B98AECB77542B0D0720D8358D96D14C
Client empfängt 1B4BA8037D0EF2119A8E9FE15BF94E2B3EEBB6EA53E3DD9B62D668F41801ED0B8C336B98AECB77542B0D0720D8358D96D14C
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 05.07.07 10:52
Das ist kein Fehler der Komponente, sondern eine bewusste Eigenart der TCP API. Um die Trennung der Pakete musst Du dich ggf. selber probieren.
Einzige Möglichkeit hier ist, einen Block-Chiffre zu nutzen, der Positionsuabhängig\Block-Unabhängig ist.
Edit: Bzw. dafür sorgen, dass Du nach jedem Paket den Status des Chiffre speicherst und mit diesem beim nächsten Paket fortsetzt. Damit hast Du dann nämlich den Fall, dass du einen langen Datenstrom hast und Sender\Empfänger synchron laufen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Zuletzt bearbeitet von BenBE am Do 05.07.07 11:01, insgesamt 1-mal bearbeitet
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 05.07.07 11:00
Moin!
(Auf die Frage hab´ ich schon gewartet... )
Sko hat folgendes geschrieben: | ich habe mit deinen Komponenten einen Chat gebastelt und wollte nun die Verschlüsselungsereignisse benutzen. Dazu habe ich eine RCx-Unit von negaH benutzt. |
Du verwendest also eine kontextabhängige Verschlüsselung; dabei ist wichtig zu wissen, dass diese Verschlüsselungen bei Streams positionsabhängig sind, also immer einen kompletten Stream mit einem Kontext verschlüsseln müssen, sonst klappt´s nicht!
Es gibt 2 grundsätzlich verschiedene Ansätze, wie man mit den TNBFPAs Verschlüsselung betreiben kann:
(1) Ohne die Encryption-Ereignisse: die Nutzdaten bereits verschlüsselt an Kommandosequenzen anfügen, dabei wird dann das Transportprotokoll im Klartext übertragen und die Daten sind separat verschlüsselt
(2) Mit den Encryption-Ereignissen: hier wird die gesamte Sitzung als Stream betrachtet, der dann auch (im Kontext) verschlüsselt werden muss, es wird damit also auch das Transportprotokoll verschlüsselt
Du hast nun die Variante 1,5 verwendet weil du in den Ereignissen immer wieder einen neuen Kontext generierst. Und das klappt dann nicht, weil damit die Entschlüsselung nicht mehr klar kommt (durch das interne Caching der Komponente).
Deshalb: entweder (1) verwenden und nur die Nutzdaten verschlüsseln (das kannst du dann wie schon von dir vorgestellt mit jeweils separatem Kontext machen) oder (2) korrekt verwenden. Nämlich:
im Server:
- beim OnCreatePA den Kontext erstellen
- in den Ereignissen verwenden
- beim OnDestroyPA den Kontext freigeben
im Client:
- im OnReset den Kontext anlegen
- in den Ereignissen verwenden
- im OnDisconnect den Kontext freigeben
Fazit: für kontextabhängige Verschlüsselungen muss der Konktext auch für die gesamte Sitzungsdauer beibehalten werden.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Do 05.07.07 11:10
Danke für eure Antworten
Also brauche ich für jeden Client einen eigenen TRCxContext ? Dann werd ich den an den ProtokollAdapter mit dran hängen, oder hab ich was falsch verstanden?
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 05.07.07 11:25
Moin!
Sko hat folgendes geschrieben: | Also brauche ich für jeden Client einen eigenen TRCxContext ? Dann werd ich den an den ProtokollAdapter mit dran hängen, oder hab ich was falsch verstanden? |
Yip, genau so hab´ ich mir das gedacht.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Do 05.07.07 13:07
Hmm, das wollte auch nicht so richtig, darum hab ich mich jetzt für Variante 1 entschieden, das geht ganz gut, danke für deine Hilfe.
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 05.07.07 13:10
@NArses: Kannst Du für die Variante 2 mal ein ganz kleines Demo schreiben???
Wünschenswert dabei wäre mit Beispiel, wie man während der Verbindung die Verschlüsslung an- und ausschalten kann (d.h. über einen Protokoll-Befehl dynamisch festlegen kann, was verschlüsselt wird und was nicht ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 05.07.07 13:55
Moin!
Sko hat folgendes geschrieben: | Hmm, das wollte auch nicht so richtig, |
Hm, OK, ist auch nicht soo ganz einfach, geb ich zu.
Sko hat folgendes geschrieben: | darum hab ich mich jetzt für Variante 1 entschieden, das geht ganz gut, danke für deine Hilfe. |
Fein, viel Erfolg noch.
BenBE hat folgendes geschrieben: | Kannst Du für die Variante 2 mal ein ganz kleines Demo schreiben? |
Ja, ich merk´ schon, das wird wohl nötig sein. Ich mach mal eins.
BenBE hat folgendes geschrieben: | Wünschenswert dabei wäre mit Beispiel, wie man während der Verbindung die Verschlüsslung an- und ausschalten kann (d.h. über einen Protokoll-Befehl dynamisch festlegen kann, was verschlüsselt wird und was nicht ... |
Das geht nicht Variante (1) nehmen. Wenn (2), dann über die gesamte Verbindung.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Do 05.07.07 20:55
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 06.07.07 01:04
Moin!
Leider war im TProtocolAdapter noch ein sehr fieser kleiner Bug, der allerdings nur bei Verschlüsselung und mehr als einer Verbindung zum Tragen kam... (da ich bisher die Verschlüsselung als "nice-to-have-feature" nicht wirklich verwendet habe und in meinem Testprojekt immer nur eine Verbindung verwendet wird, ist mir das bisher leider nicht aufgefallen ). Togal, neue Version v1.08 der Komponente im ersten Beitrag zum Download; bei der Gelegenheit auch gleich noch was zu Verschlüsselung in die Doku (v1.05) eingepflegt.
Jetzt zum versprochenen Beispiel für verschlüsselte Kommunikation (das komplette Projekt ist auch im Download-Archiv enthalten, s. erster Beitrag). Dazu werden wir diese kleine kontextsensitive Doof-Verschlüsselung verwenden, um jetzt nicht auch noch mit einem "komplizierten" Verfahren zu kämpfen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| type TDemoCipher = class(TObject) private FEncryptionKey: Byte; FDecryptionKey: Byte; procedure DoEncryption(var Buffer; const Size: Integer; var Key: Byte); public procedure Reset; procedure Encrypt(var Buffer; const Size: Integer); procedure Decrypt(var Buffer; const Size: Integer); end;
implementation
procedure TDemoCipher.Reset; begin FEncryptionKey := 0; FDecryptionKey := 0; end;
procedure TDemoCipher.DoEncryption(var Buffer; const Size: Integer; var Key: Byte); var i: Integer; begin for i := 0 to Size-1 do begin TByteArray(Buffer)[i] := TByteArray(Buffer)[i] xor Key; Inc(Key); end; end;
procedure TDemoCipher.Encrypt(var Buffer; const Size: Integer); begin DoEncryption(Buffer,Size,FEncryptionKey); end;
procedure TDemoCipher.Decrypt(var Buffer; const Size: Integer); begin DoEncryption(Buffer,Size,FDecryptionKey); end; |
Folgender Code ist im Server des Chat-Demos, das als Basis dient, zu ergänzen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TServerMain.NBFPAServer1CreatePA(Sender: TObject; PA: TProtocolAdapter); begin PA.RefObject := TDemoCipher.Create; PA.OwnsRefObject := TRUE; end;
procedure TServerMain.NBFPAServer1EncryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin TDemoCipher(PA.RefObject).Encrypt(Buffer,Size); end;
procedure TServerMain.NBFPAServer1DecryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin TDemoCipher(PA.RefObject).Decrypt(Buffer,Size); end; |
Und hier die Änderungen/Ergänzungen im Client-Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure TClientMain.FormCreate(Sender: TObject); begin FDemoCipher := TDemoCipher.Create; NBFPAClient1ConnectionStateChange(Self); end;
procedure TClientMain.NBFPAClient1Reset(Sender: TObject; PA: TProtocolAdapter); begin FDemoCipher.Reset; end;
procedure TClientMain.NBFPAClient1EncryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin FDemoCipher.Encrypt(Buffer,Size); end;
procedure TClientMain.NBFPAClient1DecryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin FDemoCipher.Decrypt(Buffer,Size); end;
procedure TClientMain.FormDestroy(Sender: TObject); begin FDemoCipher.Free; end; |
Mit diesen Ergänzungen läuft die Kommunikation jetzt verschlüsselt ab.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 09.07.07 18:45
Moin!
Tja das Thema Verschlüsselung hätte wohl noch etwas intensivere Aufarbeitung vertragen können... Leider war noch ein Bug diesbezüglich drin neue Version v1.09 der Komponente im ersten Beitrag.
Aber als "Entschädigung" hier noch ein Vorschlag, wie man eine vollduplex-symmetrische RC4-Verschlüsselung integrieren könnte. Zunächst die RC4-Adapter-Klasse, um eine RC4-Unit an den Protokoll-Adapter anzuknoten (die Aufrufe der RC4-Unit sind ggfs. entsprechend anzupassen, je nach Unit eben):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| uses ..., RC4;
type TRC4Adapter = class(TObject) private FEncryptionContext: TRC4Context; FDecryptionContext: TRC4Context; public constructor Create(const AKey: String); destructor Destroy; override; procedure Reset(const AKey: String); procedure Encrypt(var Buffer; const Size: Integer); procedure Decrypt(var Buffer; const Size: Integer); end;
implementation
constructor TRC4Adapter.Create(const AKey: String); begin inherited Create; Reset(AKey); end;
destructor TRC4Adapter.Destroy; begin RC4Done(FEncryptionContext); RC4Done(FDecryptionContext); inherited; end;
procedure TRC4Adapter.Reset(const AKey: String); begin RC4Init(FEncryptionContext,AKey); RC4Init(FDecryptionContext,AKey); end;
procedure TRC4Adapter.Encrypt(var Buffer; const Size: Integer); begin RC4Code(FEncryptionContext,Buffer,Buffer,Size); end;
procedure TRC4Adapter.Decrypt(var Buffer; const Size: Integer); begin RC4Code(FDecryptionContext,Buffer,Buffer,Size); end; |
Die Einbindung ins Demo-Server-Projekt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TServerMain.NBFPAServer1CreatePA(Sender: TObject; PA: TProtocolAdapter); begin PA.RefObject := TRC4Adapter.Create('*geheim*'); PA.OwnsRefObject := TRUE; end;
procedure TServerMain.NBFPAServer1EncryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin TRC4Adapter(PA.RefObject).Encrypt(Buffer,Size); end;
procedure TServerMain.NBFPAServer1DecryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin TRC4Adapter(PA.RefObject).Decrypt(Buffer,Size); end; |
Und hier noch der Client:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure TClientMain.FormCreate(Sender: TObject); begin FRC4Adapter := TRC4Adapter.Create(''); NBFPAClient1ConnectionStateChange(Self); end;
procedure TClientMain.NBFPAClient1Reset(Sender: TObject; PA: TProtocolAdapter); begin FRC4Adapter.Reset('*geheim*'); end;
procedure TClientMain.NBFPAClient1EncryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin FRC4Adapter.Encrypt(Buffer,Size); end;
procedure TClientMain.NBFPAClient1DecryptData(Sender: TObject; PA: TProtocolAdapter; var Buffer; const Size: Integer); begin FRC4Adapter.Decrypt(Buffer,Size); end;
procedure TClientMain.FormDestroy(Sender: TObject); begin FRC4Adapter.Free; end; |
Viel Erfolg!
cu
Narses
//EDIT: hatte vergessen, den RC4-Kontext im Destruktor der Adapterklasse wieder zu leeren, ist jetzt aber mit drin.
_________________ There are 10 types of people - those who understand binary and those who don´t.
Zuletzt bearbeitet von Narses am Di 10.07.07 20:51, insgesamt 1-mal bearbeitet
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Di 10.07.07 06:34
Super, werd ich gleich mal ausprobieren, Danke
|
|
Narses
Beiträge: 10181
Erhaltene Danke: 1254
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 10.07.07 09:16
Moin!
Sko hat folgendes geschrieben: | Super, werd ich gleich mal ausprobieren, Danke |
Bitte Rückmeldung erwünscht.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Sko
Hält's aus hier
Beiträge: 6
Win XP
Turbo Delphi Professional
|
Verfasst: Di 10.07.07 20:19
Funktioniert super, keine Probleme, alles läuft wie´s soll, vielen Dank nochmal
|
|
|