Połączenia szyfrowane protokołu Tlen.pl

Udało mi się wreszcie poświęcić chwilkę na napisanie publikacji na temat połączeń szyfrowanych w tlenie. Kilka dni temu wraz z andkiem analizowaliśmy szczegóły techniczne działania tej funkcjonalności. Jest to pierwsza publikacja z cyklu "Tlen.pl bez tajemnic", planuje jeszcze kilka publikacji, których tematem będzie autoryzacja pluginów, kodowanie plików konfiguracyjnych komunikatora, format archiwum itd...

Do tej pory żadna dostępna biblioteka, bądź klasa do obsługi protokołu komunikatora tlen.pl nie umożliwiała wykorzystywania szyfrowanych połączeń miedzy klientem a serwerem. Mimo iż szyfrowanie zostało wprowadzone już w wersji 3 protokołu tlen.pl, w wersji 3.90 klienta, wydanej w czerwcu 2003 roku.

Może, dlatego że nikt z (nie)zwykłych użytkowników nie był tym zainteresowany, albo nikomu nie chciało się zagłębiać w szczegóły techniczne, bądź, co gorsza mało kto wiedział i pewnie nadal mało kto wie o tym, że domyślnie Tlen wykorzystuje szyfrowaną transmisje.

O tym ze Tlen wykorzystuje algorytm RSA i AES było wiadomo od dawna. Brakowało tylko szczegółów technicznych działania tej implementacji w Tlenie.
Jako, że ciekawiło mnie to, a dodatkowo miło byłoby w xiT++ wprowadzić jako pierwsi szyfrowane połączenia, postanowiłem zbadać i przeanalizować ten problem.

Po krótkim wstępie czas najwyższy przejść do konkretów.

Transmisja pomiędzy klientem a serwerem jest szyfrowana przy użyciu 128-bitowego algorytmu AES, gdzie do uzgadniania tegoż klucza wykorzystuje się 512-bitowy algorytm RSA, co zapewnia optymalną kombinację bezpieczeństwa i wydajności. Szyfrowanie wszystkich informacji algorytmem RSA byłoby nieopłacalne, czasochłonne i najbardziej "zabójcze" dla serwera.

Szczegółowy opis protokołu tlen.pl można znaleźć w Nieoficjalnej dokumentacji protokołu Tlen.pl. Tutaj ograniczymy się tylko do ważnych z naszego punktu widzenia fragmentów.

Po wysłaniu inicjalizacji połączenia szyfrowanego:

<s s='1' v='9' t='06000224'>

Serwer odeśle nam:

<s i='456C287C' c='1' s='1' k1='10001' k2='1554a7873b24bb3e0c0101
675e018fe184fa3c9e66e80a4c33b6f2552e7e9c2b671865e1b56ce1701804c55
0cf124a8614b25e1f66c1c58a629f7be94b3650fd' k3='717765727479756961
73646667686a6b'>

Łatwo zauważyć ze wśród otrzymanych danych, uwagę przyciągają wartości atrybutów k1...k3 przypominające jakieś klucze, czy hasze. Dokładniejsze przeznaczenie tych danych jest następujące:

  • k1 - klucz publiczny RSA (e)
  • k2 - klucz publiczny RSA (pq)
  • k3 - wektor inicjujący serwera (IV)

Generujemy 128-bitowy klucz AES, który szyfrujemy algorytmem RSA przy użyciu kluczy publicznych k1 i k2. Generujemy także wektor inicjujący klienta. A otrzymane dane odsyłamy do serwera:

<cipher k1='8bf1d8db124afbcb808e0405eb4af8b27242ee0c455f31a1c6b58
0af600b0dcacbc0378cf02a72050bb784d7765ba9a41a8c7d7c622e4a8acc25a3
e1b829a70' k2='79e67e38a43961cf8d1a1377e5e9fe90'/>

gdzie:

  • k1 - zaszyfrowany klucz AES
  • k2 - wektor inicjujący klienta (IV)

Serwer potwierdzi otrzymanie wymaganych informacji:

<cipher type='ok'/>

Na co my odpowiadamy:

<cipher type='ok'/>

Tyle, że nasza odpowiedz jest już zaszyfrowana algorytmem AES.

Dalsza transmisja miedzy klientem a serwerem jest szyfrowana.

Szyfrowanie AES pracuje na 16 bajtowych blokach danych w trybie kodowania CBC, gdzie każdy blok przed szyfrowaniem przekształcany jest funkcją XOR z szyfrogramem uzyskanym z szyfrowania poprzedniego bloku. Pierwszy blok szyfrowany jest wektorem inicjującym wygenerowanym przez klienta i odesłanym serwerowi.

Poniższy rysunek powinien rozwiać wszelkie wątpliwości.

Cipher Block Chaining (CBC) mode encryption

Deszyfrowanie jest analogiczne. Wykorzystany jest tutaj wektor inicjujący otrzymany od serwera.

Cipher Block Chaining (CBC) mode decryption

Pozostaje jeszcze tylko dodać, że dane mniejsze od rozmiaru bloku (16 bajtów), wyrównywane są do granicy bloku spacjami.

Teraz transmisja szyfrowana komunikatora Tlen.pl nie kryje przed nami już żadnych tajemnic. Nie będę tutaj zamieszczał żadnej przykładowej implementacji, każdy sobie z tym powinien poradzić, jeśli nie to chyba powinien się dokształcić ;)

Swój wkład w rozwiązanie tej "zagadki" miał także andk, za co należą mu się podziękowania za poświęcony czas ;) Na swojej stronie zamieścił krótki, zwięzły, czysto techniczny opis inicjalizacji połączenia szyfrowanego w protokole tlen.pl.

[Wykorzystane rysunki pochodzą z angielskiej wikipedii, dostępne na zasadach public domain.]

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *