Wymiana szyfrowanych komunikatów przez sieć – jak w godzinę stworzyć własne narzędzia w Tcl/Tk

logoLargeJeśli znajdziesz się w potrzebie szybkiego uruchomienia bezpiecznej wymiany danych pomiędzy stacjami w sieci, a na dodatek zechcesz tę wymianę zrealizować w oparciu o dowolny wybrany, wysoki numer portu po stronie serwera (powyżej 1024, aż do 65535), to możesz w tym celu z powodzeniem użyć własnych narzędzi skryptowych. Ich opracowanie może dosłownie zająć zaledwie kilkanaście minut, bo w pełni użyteczne oprogramowanie nie musi przecież zawierać graficznego interfejsu użytkownika. Wystarczy jeśli zadziała poprawnie z poziomu konsoli znakowej. Nie musisz polegać na żadnym gotowym oprogramowaniu i konieczności instalowania czegokolwiek, no może poza interpreterem języka Tcl/Tk i wymaganymi bibliotekami. Nie do pogardzenia też jest to, że w efekcie końcowym otrzymujesz kod uniwersalny, który pozostaje całkowicie niezależny od rodzaju platformy i systemu operacyjnego. Dodam, że jeśli nie masz jeszcze TCL-a, to możesz za darmo pobrać z Internetu dystrybucję ActiveState TCL Community Edition (dla Windows, Unix-ów i MacOS).

Zaprezentowane rozwiązania skryptowe klienta i serwera, napisane zostały, jak już wspomniałem, w języku TCL. Posiadają graficzny interfejs użytkownika oparty o bibliotekę Tk, bo pomyślałem, że kolejnym etapem pracy nad nimi będzie opracowanie bezpiecznego komunikatora sieciowego z estetycznym GUI. W aktualnej wersji klient nawiązuje połączenie TCP do wskazanego serwera, nasłuchującego gdzieś w sieci pod podanym adresem IP i na podanym porcie, szyfruje tekst wprowadzany przez użytkownika stosując algorytm Blowfish i posługując się w tym celu podanym kluczem.

crypto_clientSerwer przyjmuje połączenia od klientów, czyta szyfrowane dane na porcie TCP, na którym działa, odszyfrowuje je tym samym kluczem, bo przecież Blowfish to symetryczny algorytm kryptograficzny i prezentuje wynik swojego działania w oknie graficznej konsoli.

Przykładowy zrzut ekranu ilustrujący interfejs klienta pokazuje co prawda, że użyto adresu pętli zwrotnej (127.0.0.1) umożliwiającego skomunikowanie z sobą klienta i serwera na tym samym komputerze, lecz nic nie stoi rzecz jasna na przeszkodzie, by klientów i serwer dzieliły nawet granice kontynentów. Jeśli tylko będzie zapewniona możliwość komunikacji na wybranych portach, to takowa komunikacja bez przeszkód nastąpi, co zostało przeze mnie przetestowane.

crypto_server

Skrypty są prototypami, choć w pełni działającymi. Z łatwością można je wzbogacić wedle uznania o kolejne funkcjonalności. Jakie funkcjonalności mam na myśli? Otóż chociażby takie:

  • Arbitralna zmiana lub umożliwienie użytkownikom wyboru spośród kilku algorytmów kryptograficznych (na przykład 3DES, AES-128, AES-192, AES-256, Idea, TwoFish, Camelia itp.) oraz różnych trybów ich działania.
  • Uwierzytelnienie dwustronne klienta i serwera w oparciu o certyfikaty X.509.
  • Obsługę transmisji binarnej, nie tylko tekstu (plików, muzyki, grafiki itp.).
  • Zbudowanie pełnej funkcjonalności komunikatora sieciowego.

Te i jeszcze inne funkcjonalności są możliwe do opracowania i do w miarę szybkiego wdrożenia. Jeśli wpadniecie na jakiś ciekawy pomysł wykraczający ponad to, co napisałem wcześniej, dajcie mi proszę znać w komentarzu do artykułu.

Tymczasem życzą Wam miłej zabawy ze „skryptowaniem”.

Oto kod serwera:

package require base64
package require blowfish

proc encrypt_message {plaintext cryptokey} {
   set ciphertext [blowfish::blowfish -mode ecb -dir encrypt -key $cryptokey "$plaintext"]
   set ciphertext [::base64::encode $ciphertext]
   return $ciphertext
}

proc decrypt_message {ciphertext cryptokey} {
   set ciphertext [::base64::decode $ciphertext]
   set plaintext [blowfish::blowfish -mode ecb -dir decrypt -key $cryptokey "$ciphertext"]
   return $plaintext
}

proc accept {chan addr port} {
   global key
   set message [gets $chan] 
   .mainfr.dispfr.consoletxt insert end "Encrypted: $message" distinguish
   .mainfr.dispfr.consoletxt insert end "\n"
   set message [decrypt_message $message $key]
   .mainfr.dispfr.consoletxt insert end "Decrypted: $message"
   .mainfr.dispfr.consoletxt insert end "\n"
   puts $chan OK
   close $chan
}

proc server_start {port} {
   if {[catch {socket -server accept $port}]} {
      tk_messageBox -message "Server start failed!" -title "Alert"
      return
   }
   tk_messageBox -message "Server started at port: $port"
   .mainfr.ctrlfr.gobt configure -text "Server started" -state disabled
   vwait forever    
}

labelframe .mainfr -text "Crypto message server"
frame .mainfr.paramfr
label .mainfr.paramfr.portlb -text "Port: "
entry .mainfr.paramfr.portent -width 10 -textvariable port
label .mainfr.paramfr.keylb -text "Crypto key: "
entry .mainfr.paramfr.keyentr -width 15 -textvariable key

labelframe .mainfr.dispfr -text "Console"

text .mainfr.dispfr.consoletxt -yscrollcommand ".srl_yd set" -xscrollcommand ".srl_xd set" -wrap none -height 10
.mainfr.dispfr.consoletxt tag configure distinguish -foreground red -relief solid -borderwidth 1
scrollbar .srl_yd -command ".mainfr.dispfr.consoletxt yview" -orient v
scrollbar .srl_xd -command ".mainfr.dispfr.consoletxt xview" -orient h

frame .mainfr.ctrlfr
button .mainfr.ctrlfr.gobt -text "Start server" -command {server_start $port}
button .mainfr.ctrlfr.exitbt -text "Exit" -command {exit}

set port 12345
set key "S3CyouR3!"
set ciphertext ""

pack .mainfr -expand 1 -fill both -ipadx 5
pack .mainfr.paramfr -expand 1 -fill both
pack .mainfr.paramfr.portlb .mainfr.paramfr.portent .mainfr.paramfr.keylb .mainfr.paramfr.keyentr -side left -fill x -expand 1 -padx 5 -pady 2
pack configure .mainfr.paramfr.portlb -expand 0 -anchor w
pack configure .mainfr.paramfr.keylb -expand 0 -anchor w

pack .mainfr.dispfr -expand 1 -fill both
pack .srl_yd -in .mainfr.dispfr -fill y -side right -expand 1
pack .srl_xd -in .mainfr.dispfr -fill x -side bottom -expand 1
pack .mainfr.dispfr.consoletxt -side left -expand 1 -fill both

pack .mainfr.ctrlfr -expand 1 -fill both -ipadx 5
pack .mainfr.ctrlfr.gobt -fill x
pack .mainfr.ctrlfr.exitbt -fill x

wm title . "Crypto message server - Janusz Nawrat (2015)"
wm resizable . 0 0

Oto kod klienta:

package require base64
package require blowfish

proc encrypt_message {plaintext cryptokey} {
   set ciphertext [blowfish::blowfish -mode ecb -dir encrypt -key $cryptokey "$plaintext"]
   set ciphertext [::base64::encode $ciphertext]
   return $ciphertext
}

proc decrypt_message {ciphertext cryptokey} {
   set ciphertext [::base64::decode $ciphertext]
   set plaintext [blowfish::blowfish -mode ecb -dir decrypt -key $cryptokey "$ciphertext"]
   return $plaintext
}

proc send_message {address port message} {
   global key
   if {[catch {socket $address $port} chan]} {
      tk_messageBox -message "Problem with opening TCP socket $address/$port" -title "Error"
      return
   }
   set line $message
   puts $chan [encrypt_message $line $key]                
   flush $chan                     
   close $chan 
}

set message "Message: "

labelframe .mainfr -text "Crypto message client"
frame .mainfr.paramfr
label .mainfr.paramfr.adrlbl -text "Destination IP Address: "
entry .mainfr.paramfr.adrent -width 15 -textvariable address
label .mainfr.paramfr.portlb -text "Port: "
entry .mainfr.paramfr.portent -width 10 -textvariable port
label .mainfr.paramfr.keylb -text "Crypto key: "
entry .mainfr.paramfr.keyentr -width 15 -textvariable key

labelframe .mainfr.dispfr -text "Console"

entry .mainfr.dispfr.consolentr -width 20 -textvariable message

frame .mainfr.ctrlfr
button .mainfr.ctrlfr.gobt -text "Send" -command {send_message $address $port $message}
button .mainfr.ctrlfr.exitbt -text "Exit" -command {exit}

set address "127.0.0.1"
set port 12345
set key "S3CyouR3!"

pack .mainfr -expand 1 -fill both -ipadx 5
pack .mainfr.paramfr -expand 1 -fill both
pack .mainfr.paramfr.adrlbl .mainfr.paramfr.adrent .mainfr.paramfr.portlb .mainfr.paramfr.portent \
     .mainfr.paramfr.keylb .mainfr.paramfr.keyentr -side left -fill x -expand 1 -padx 5 -pady 2
pack configure .mainfr.paramfr.portlb -expand 0 -anchor w
pack configure .mainfr.paramfr.keylb -expand 0 -anchor w

pack .mainfr.dispfr -expand 1 -fill both
pack .mainfr.dispfr.consolentr -side left -expand 1 -fill x -pady 8 -padx 5

pack .mainfr.ctrlfr -expand 1 -fill both -ipadx 5 -ipady 2
pack .mainfr.ctrlfr.gobt .mainfr.ctrlfr.exitbt -fill x -side left -expand 1

wm title . "Crypto message client - Janusz Nawrat (2015)"
wm resizable . 0 0

Informacje Janusz Nawrat
Just ordinary man who likes thinking...

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

TOMASZ WEŁNA

artysta grafik | wykładowca

PRACOWNIA OKO

Szkoła Rysunku Malarstwa i Grafiki DR TOMASZA WEŁNY | KRAKÓW | Plac Matejki 10 | tel 691 81 75 74

Piękno neurobiologii

Blog Jerzego Vetulaniego

Teoria muzyki, zasady muzyki, podstawy muzyki

Teoria muzyki, zasady muzyki, podstawy muzyki - czyli to co każdy amator muzyki wiedzieć powinien :)

Personal Development & Inspirations

Przemyślenia i refleksje, którymi warto się podzielić (blog by Janusz Nawrat)

Business IT Cooperation Platform

Biznes i IT - dwa światy, które muszą współdziałać

%d bloggers like this: