Na początek trochę wiedzy historycznej. Firma Netscape w 1994 roku opracowała pierwszą wersję protokołu SSL, który przez następnych kilka lat był wydawany w kolejnych wersjach. W pewnym momencie nazwa uległa zmianie z SSL na TLS i formalnie pod tą nazwą znane są kolejne wersje certyfikatów. Umownie jednak przyjęło się, że mówiąc o certyfikatach TLS, nazywamy je certyfikatami SSL.
Powyżej wspomnieliśmy o protokole TLS (wcześniej SSL) oraz certyfikacie SSL. Czym różnią się te dwie rzeczy? Zacznijmy od protokołu TLS. Ponieważ w modelu ISO/OSI działa on w warstwie prezentacji, możliwe jest zabezpieczenie dzięki niemu wyższej warstwy – aplikacji. Obecnie, każda z warstw w modelu ISO/OSI zawiera mechanizmy zapewniające zabezpieczenia. W poniższej tabeli przedstawiono przykładowe protokoły w kolejnych warstwach modelu ISO/OSI.
Warstwa modelu ISO/OSI | Przykładowe protokoły modelu ISO/OSI |
Warstwa aplikacji | HTTP, FTP, SSH, DNS, DHCP |
Warstwa prezentacji | MIME , XDR , SSL , TLS |
Warstwa sesji | NetBIOS , SAP |
Warstwa transportowa | TCP , UDP |
Warstwa sieciowa | IP (IPv4, IPv6) , IPX , ICMP , IGMP , IPsec |
Warstwa łącza danych | ARP , LAPB |
Warstwa fizyczna | Ethernet, DSL |
Na szczegółowy opis modelu ISO/OSI poświęcimy w przyszłości oddzielny post.
Wspomniane wyżej „zabezpieczenie” protokołu TLS polega na:
- szyfrowaniu danych,
- zapewnieniu integralności transmisji danych,
- potwierdzeniu tożsamości serwera,
- opcjonalnym potwierdzeniu tożsamości klienta.
Skoro wiemy już, czym jest i jakie zadanie ma protokół TLS, pozostał nam certyfikat SSL. Najprościej będzie go zrozumieć na przykładzie użycia samego protokołu.
Działanie protokołu SSL
Pierwszą sesję SSL czyli uścisk dłoni (handshake), można zaprezentować w kilku krokach:
Client Server
-----------------------------------------------------------
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
- Początkowo użytkownik przesyła na serwer niezabezpieczoną, czystą wiadomość ClientHello, która oznacza deklarację połączenia SSL. Ponadto, zawiera ona takie informacje jak:
- server_version – maksymalna możliwa do użycia wersja protokołu,
- (client) random – czyli 32 bajty (z czego 28 mają być wygenerowane silnym generatorem liczb),
- session_id – identyfikator używany do ponowienia sesji handshake w skróconej wersji (abbreviated handshake),
- cipher_suite – lista zestawów szyfrów, które zna klient. Jeden zestaw to 16 bitowy identyfikator, który definuje zestaw algorytmów,
- compression_method – lista algorytmów kompresji danych, które zna klient ,
- extensions – rozszerzenia (opcjonalne).
- Serwer odpowiada wiadomością ServerHello, który przechowuje:
- server_version – wybraną z przekazanych przez klienta wersję protokołu,
- (server) random – analogicznie i niezależnie do (client) random,
- session_id – identyfikator dla obecnego połączenia. Jeśli ClientHello.session_id nie był pusty i został uzupełniony (np. z cache), to serwer go sprawdza, a w momencie znalezienia go, przechodzi do punktu Finished. Wrócimy do tego w późniejszym etapie,
- cipher_suite – wybrany zestaw szyfrów,
- compression_method – wybrany algorytm kompresji,
- extensions – rozszerzenia (opcjonalne).
- Serwer przesyła Certificate*, który przechowuje klucz publiczny,
- Serwer przesyła ServerKeyExchange*, czyli kilka dodatkowych informacji niebzędnych do wymiany kluczy, jeśli te zdefiniowane w Certificate są niewystarzające,
- Serwer przesyła CertificateRequest*, żądanie skierowane do klienta, z prośbą o identyfikowanie się za pomocą własnego certyfikatu. Wiadomość zawiera listę „root certificates”, czyli punkty za których pomocą będzie przeprowadzana walidacja certyfikatu,
- Serwer przesyła ServerHelloDone, tj. wiadomość o zerowej długości, informując tym samym klienta, że czas na jego odpowiedzi,
- Klient odpowiada Certificate*, jeśli serwer go zarządał,
- Klient odpowiada ClientKeyExchange, czyli losowa wartość zaszyfrowana kluczem serwera,
- Klient odpowiada CertificateVerify*. Jest to najprościej mówiąc podpis cyfrowy, utworzony na podstawie poprzednich wiadomości, który jest jednocześnie potwierdzeniem dla serwera, że klient wykorzystuje klucz publiczny z zakodowanego przez niego certyfikatu,
- Obie strony, najpierw klient, a potem serwer, przesyła ChangeCipherSpec, tj. wiadomość będącą potwierdzeniem odbiorcy, że kolejne rekordy będą już szyfrowane za pomocą wskazanych wcześniej zestawów szyfrów i kluczy.
- Wiadomości Finished, które są przesyłane bezpośrednio po ChangeCipherSpec, są pierwszymi zaszyfrowanymi wartościami kryptograficznymi, które jednocześnie zawierają w sobie wszystkie poprzednie wiadomości. W ten sposób obie strony są w stanie zweryfikować, że rozmawiają między sobą, a ich wiadomości nie były modyfikowane.
Po całości klient i serwer są w stanie wymieniać zaszyfrowane dane. Jak wspomnieliśmy pierwszej, jest to pierwszy uścisk dłoni (handshake). W przypadku kolejnych (abbreviated handshakes), wykres komunikacji przedstawia się następująco:
Client Server
-----------------------------------------------------------
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
Wróćmy na chwilę do ServerHello.session_id. Wspomnieliśmy, że serwer w momencie rozpoznania ClientHello.session_id, pomija cały proces i od razu przechodzi od punktu Finished. Taka sesja jest zapamiętywana przez serwer www na nawet kilkanaście godzin.
*Informacje przesyłane opcjonalnie, zależne od min. użytych zestawów szyfrów.
Czytanie certyfikatów w konsoli
W celu sprawdzenia certyfiaktu SSL, możemy użyć narzędzia nmap lub openssl. Znając konkretny adres oraz port, wpisujemy poniższą komendę:
nmap -p 443 --script ssl-cert google.com
W odpowiedzi otrzymujemy sporą garść informacji:
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-19 01:48 CEST
Nmap scan report for google.com (172.217.16.46)
Host is up (0.023s latency).
Other addresses for google.com (not scanned): 2a00:1450:401b:804::200e
rDNS record for 172.217.16.46: muc03s08-in-f46.1e100.net
PORT STATE SERVICE
443/tcp open https
| ssl-cert: Subject: commonName=*.google.com/organizationName=Google LLC/stateOrProvinceName=California/countryName=US
| Subject Alternative Name: DNS:*.google.com, DNS:*.android.com, DNS:*.appengine.google.com, DNS:*.bdn.dev, DNS:*.cloud.google.com, DNS:*.crowdsource.google.com, DNS:*.datacompute.google.com, DNS:*.flash.android.com, DNS:*.g.co, DNS:*.gcp.gvt2.com, DNS:*.gcpcdn.gvt1.com, DNS:*.ggpht.cn, DNS:*.gkecnapps.cn, DNS:*.google-analytics.com, DNS:*.google.ca, DNS:*.google.cl, DNS:*.google.co.in, DNS:*.google.co.jp, DNS:*.google.co.uk, DNS:*.google.com.ar, DNS:*.google.com.au, DNS:*.google.com.br, DNS:*.google.com.co, DNS:*.google.com.mx, DNS:*.google.com.tr, DNS:*.google.com.vn, DNS:*.google.de, DNS:*.google.es, DNS:*.google.fr, DNS:*.google.hu, DNS:*.google.it, DNS:*.google.nl, DNS:*.google.pl, DNS:*.google.pt, DNS:*.googleadapis.com, DNS:*.googleapis.cn, DNS:*.googlecnapps.cn, DNS:*.googlecommerce.com, DNS:*.googledownloads.cn, DNS:*.googlevideo.com, DNS:*.gstatic.cn, DNS:*.gstatic.com, DNS:*.gstaticcnapps.cn, DNS:*.gvt1.com, DNS:*.gvt2.com, DNS:*.metric.gstatic.com, DNS:*.urchin.com, DNS:*.url.google.com, DNS:*.youtube-nocookie.com, DNS:*.youtube.com, DNS:*.youtubeeducation.com, DNS:*.youtubekids.com, DNS:*.yt.be, DNS:*.ytimg.com, DNS:android.clients.google.com, DNS:android.com, DNS:developer.android.google.cn, DNS:developers.android.google.cn, DNS:g.co, DNS:ggpht.cn, DNS:gkecnapps.cn, DNS:goo.gl, DNS:google-analytics.com, DNS:google.com, DNS:googlecnapps.cn, DNS:googlecommerce.com, DNS:googledownloads.cn, DNS:source.android.google.cn, DNS:urchin.com, DNS:www.goo.gl, DNS:youtu.be, DNS:youtube.com, DNS:youtubeeducation.com, DNS:youtubekids.com, DNS:yt.be
| Issuer: commonName=GTS CA 1O1/organizationName=Google Trust Services/countryName=US
| Public Key type: ec
| Public Key bits: 256
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-03-23T08:18:59
| Not valid after: 2021-06-15T08:18:58
| MD5: b075 896c 843f 374e d237 4807 b992 09a7
|_SHA-1: 2f5c 43f2 d253 75f8 0aac 79a2 9087 2697 e98a c90a
Nmap done: 1 IP address (1 host up) scanned in 0.43 seconds
Po szczegółowe, nieco mniej czytelne informacje użyjemy komendy:
echo | openssl s_client -showcerts -servername google.com -connect google.com:443 2>/dev/null | openssl x509 -inform pem -noout -text
Struktura certyfikatu została opisana poniżej, choć nad nią samą nie będziemy się dłużej rozwodzić.
- Certyfikat
- Numer wersji
- Numer seryjny
- Identyfikator algorytmu podpisu
- Nazwa wystawcy
- Okres ważności
- Nieważny przed datą
- Nieważny po dacie
- Nazwa podmiotu
- Informacje o kluczu publicznym podmiotu
- Algorytm klucza publicznego
- Klucz publiczny podmiotu
- Identyfikator emitenta (opcjonalne)
- Identyfikator podmiotu (opcjonalne)
- Rozszerzenia, informacje dodatkowe (opcjonalne)
- Certyfikat sygnatury algorytmu
- Certyfikat sygnatury
Rodzaje certyfikatów
Możemy wyróżnić trzy rodzaje certyfikatów różniących się od siebie poziomem weryfikacji identyfikacji strony. Należą do nich:
- DV (Domain Validation) – najbardziej podstawowa forma zabezpieczenia, w której dochodzi do weryfikacji posiadania domeny przez osobę wykupującą certyfikat,
- OV (Organization Validation) – aby certyfikat został wystawiony, następuje weryfikacja posiadania domeny jak i firmy, który nią zarządza,
- EV (Extended Validation) – szczegółowa weryfikacja zarówno podmiotu jak i posiadania domeny przez Urząd Certyfikacji pod kątem tożsamości firmy.
Dodatkowe informacje
O zagrożeniach z przeszłości związanych z certyfikatami i komunikacją SSL/TLS, odsyłamy tutaj.
Źródła
https://tools.ietf.org/html/rfc5246
https://jchost.pl/blog/tls/
https://pl.wikipedia.org/wiki/Transport_Layer_Security
https://students.mimuw.edu.pl/SO/Projekt04-05/temat5-g6/Danka/ssl_my.html
https://pl.wikipedia.org/wiki/X.509
https://www.ssl.com/pl/FAQ/faq-co-to-jest-ssl/
https://security.stackexchange.com/questions/20803/how-does-ssl-tls-work