TLS: Zestawy szyfrów

09 Dec 2019

ciphers  ecc  https  rsa  security  ssl  tls 

Share on:

Jedną z najważniejszych czynności podczas konfiguracji TLS jest wybór odpowiednich zestawów szyfrów. Parametr ten zmienia się częściej niż inne, zalecana konfiguracja na dziś może być nieaktualna jutro.

Omawiany w tym wpisie temat nie należy do najłatwiejszych ze względu na swoją złożoność. Pokazuje on dodatkowo, że konfiguracja TLS nie polega i nie powinna polegać na ustawieniu pewnych parametrów w ciemno (a co gorsza skopiowania ich z pierwszego lepszego źródła), tylko na przemyślanym, zweryfikowanym i racjonalnym (także jeśli chodzi o bezpieczeństwo) sposobie ich doboru. Dlatego do tematu dobrze jest podejść bardzo starannie, ponieważ wykorzystywane zestawy szyfrów w komunikacji są jedną z najistotniejszych rzeczy, które ją chronią.

Jeśli druga strona komunikacji nie obsługuje pakietu szyfrów zgodnego z Twoimi standardami, a dodatkowo cenisz bezpieczeństwo tego połączenia, nie pozwól, aby Twój system działał z pakietami szyfrów niższej jakości.

Czym jest zestaw szyfrów? #

Zestaw (pakiet) szyfrów (ang. cipher suite) to kombinacja algorytmów uwierzytelniania oraz szyfrowania, które są używane podczas negocjacji ustawień zabezpieczeń dla połączenia TLS, a także do przesyłania danych.

Zestawy szyfrów są wykorzystywane w celu zabezpieczenia przesyłanych danych, dlatego ich poprawny dobór jest tak istotny z punktu widzenia bezpieczeństwa całej komunikacji. Bez starannego wyboru zestawu szyfrów (TLSv1.3 robi to za Ciebie!) ryzykujesz negocjację ze słabym (mniej bezpiecznym i niewyprzedzającym najnowszych luk) pakietem szyfrów, który może zostać skompromitowany. Moim zdaniem dobrze przemyślana i aktualna lista wysoce bezpiecznych pakietów szyfrów jest bardzo ważna dla komunikacji TLS o wysokim poziomie bezpieczeństwa.

Pakiet szyfrów to informacja o algorytmach wykorzystanych do zapewnienia bezpiecznej komunikacji.

Podczas procesu uzgadniania protokołu TLS klient zaczyna od poinformowania serwera o obsługiwanych szyfrach. Następnie serwer porównuje te zestawy szyfrów z pakietami szyfrów, które są włączone po jego stronie. Zestawy szyfrów są zwykle ułożone w kolejności bezpieczeństwa i gdy serwer tylko znajdzie dopasowanie, informuje o tym klienta i uruchamiane są algorytmy wybranego zestawu.

Klient sugeruje pakiet szyfrów, jednak to serwer dokonuje ostatecznego wyboru. Decyzja dotycząca zestawu szyfrów zawsze leży w gestii serwera. Serwer następnie negocjuje i wybiera odpowiedni szyfr do wykorzystania w komunikacji. Jeśli serwer nie jest przygotowany do użycia żadnego z szyfrów reklamowanych przez klienta, nie zezwoli na sesję.

Jeżeli chodzi o zestawy szyfrów, to musisz wiedzieć, że są trzy sposoby ich nazewnictwa (więcej informacji znajdziesz na OpenSSL IANA Mapping):

Widzimy, że jest pewna różnica ich oznaczania, jednak każda wersja określa ten sam szyfr, który ma identyfikator 0x33. Dobrze jest zawsze posiłkować się identyfikatorem, ponieważ nie ma wtedy możliwości pomyłki. Spójrz na poniższy przykład:

Można tutaj pomylić się w interpretacji, podążając za nazwą (a różnica jest subtelna), jednak identyfikator liczbowy ewidentnie wskazuje, że nie są to te same szyfry. Pierwszy z nich oznaczony jest jako podatny i niezalecany (nie wspiera Perfect Forward Secrecy, czyli sposobu, w jaki wymieniane są klucze sesyjne) zaś drugi niweluje niedociągnięcia tego pierwszego i jest w pełni bezpieczny.

Niebezpieczny czy podatny? #

Oczywiście najlepiej jest wykorzystywać tylko te zestawy szyfrów, które uznane są za w pełni bezpieczne, i które nie posiadają żadnych znanych słabości.

Jeżeli chcesz uzyskać dodatkową wiedzę polecam świetny i krótki filmik Strong vs. Weak TLS Ciphers.

W wielu artykułach czy dokumentach pojawiają się określenia, że szyfr jest podatny lub niebezpieczny. Uważam, że klasyfikacja jest kluczowa z racji tego, że szyfrów jest bardzo dużo. Można jednak popełnić pomyłkę, przydzielając dany szyfr do nieodpowiedniej grupy — sam, dla prostoty, zawężam to pole do szyfrów bezpiecznych i niebezpiecznych. Osobiście nie lubię słowa niebezpieczny, ponieważ stoi za nim jakaś mroczna siła — według mnie dużo lepszym określeniem jest nieoptymalny lub wrażliwy.

Oryginalne źródło znajduje się na Wikipedia - Transport Layer Security

Jednak postaram się w pełni zdefiniować problem. W pierwszej kolejności przytoczę opis (nie do końca się z nim zgadzam), który znajduje się w serwisie TLS Cipher Suite Search:

Należy zdać sobie sprawę, że słaby (lepszym określeniem może być wrażliwy) nie oznacza niepewny/niebezpieczny. Jest tutaj pewna delikatna różnica: szyfr zwykle jest oznaczany jako słaby, ponieważ istnieje pewna fundamentalna wada projektowa, która utrudnia bezpieczne wdrożenie oraz sprawia, że dalsze korzystanie z danego algorytmu lub kryptosystemu stanowi potencjalne ryzyko.

Nie oznacza to od razu, że użycie takiego szyfru spowoduje totalną kompromitację bezpieczeństwa serwera czy infrastruktury. Oznacza to, że atakujący przy spełnieniu pewnych warunków może wykorzystać podatności znalezione w takich szyfrach. Szyfry takie osłabiają całą komunikację między użytkownikiem a serwerem.

Słaby szyfr jest definiowany jako algorytm szyfrowania i deszyfrowania, który wykorzystuje klucz o niewystarczającej długości (najczęściej). Zastosowanie takiego klucza w danym algorytmie otwiera możliwość (lub prawdopodobieństwo), że cały schemat szyfrowania może zostać złamany. Szyfr niebezpieczny powinien być traktowany jako taki, który ma nie jedną lukę, ale zbiór bardzo łatwych do wykorzystania luk. Na przykład DES zaczął być uważany za niepewny, głównie ze względu na jego stosunkowo krótką długość klucza, co czyni go podatnym na ataki siłowe.

Na przykład, algorytmy szyfrowania inne niż AEAD (takie jak AES_128_CBC) są uznawane za słabe. Zmiany te zostały wprowadzone z powodu wad lub możliwych luk odkrytych od czasu ostatniego wydania, które mogą powodować obniżenie bezpieczeństwa połączenia TLS.

Jeżeli masz dylematy i zastanawiasz się, w jaki sposób określać zastosowane szyfry, możesz przyjąć podejście zero-jedynkowe i klasyfikować je w znacznie prostszy sposób:

Pozwala to znacznie zawęzić pole i ułatwia wybór doboru odpowiedniego szyfru, bez zajmowania się niepotrzebnymi szczegółami.

Pamiętaj, że wykorzystanie nowoczesnych zestawów szyfrów może mieć negatywne konsekwencja dla starszych klientów, którzy najczęściej nie wspierają ich obsługi.

Przed jednoznacznym określeniem, które zestawy szyfrów będziesz wspierał, dobrym pomysłem jest analiza Twojego ruchu w celu sprawdzenia, z jakimi szyframi łączą się klienci. Pozwoli to jasno stwierdzić jakie szyfry powinieneś włączyć. Na koniec kilka interesujących statystyk (źródło: Logjam: the latest TLS vulnerability explained):

94% of the TLS connections to CloudFlare customer sites uses ECDHE (more precisely 90% of them being ECDHE-RSA-AES of some sort and 10% ECDHE-RSA-CHACHA20-POLY1305) and provides Forward Secrecy. The rest use static RSA (5.5% with AES, 0.6% with 3DES).

Z czego składa się szyfr? #

Różne algorytmy kryptograficzne są używane podczas nawiązywania połączenia, a później podczas faktycznego połączenia TLS. Zasadniczo istnieją 4 różne części pakietu szyfrów. Spójrzmy na przykładzie TLSv1.2:

Te cztery typy algorytmów są łączone w tak zwane zestawy szyfrów. Oczywiście należy jeszcze wspomnieć o długości klucza symetrycznego (128, 256) oraz trybie szyfru symetrycznego (CBC, GCM).

Na przykład szyfr:

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256

Używa do wymiany kluczy krzywej eliptycznej Diffie-Hellman w wersji efemerycznej (ECDHE), zapewniając poufność przekazywania (Perfect Forward Secrecy). Ponieważ parametry są efemeryczne (tymczasowe), są one odrzucane po użyciu, a wymienionego klucza nie można odzyskać ze strumienia ruchu oraz z pamięci serwera.

Do podpisania klucza tymczasowego służy klucz prywatny, który natomiast „podpisany” jest przez zaufany urząd certyfikacji. Dzięki temu klient jest w stanie zweryfikować, że komunikuje się z zaufanym serwerem. Nie ma tym samym możliwości odszyfrowania transmisji nawet w przypadku skompromitowania klucza prywatnego.

Następnie, RSA_WITH_AES_128_CBC_SHA256 oznacza, że algorytm uwierzytelniania używany do weryfikacji serwera i podpisywania parametrów wymiany kluczy, klucz prywatny i publiczny oraz sam certyfikat, to RSA. Natomiast wymiana klucza ECDHE jest używana w połączeniu z szyfrem symetrycznym AES-128-CBC, a do uwierzytelnienia wiadomości używany jest skrót SHA256. P256 jest rodzajem krzywej eliptycznej (zestawy szyfrów TLS i krzywe eliptyczne są czasami konfigurowane przy użyciu takiego pojedynczego ciągu).

Aby korzystać z zestawów szyfrów ECDSA, potrzebny jest certyfikat i klucz ECDSA. Aby korzystać z pakietów szyfrów RSA, potrzebujesz certyfikatu i klucza RSA. Certyfikaty ECDSA są zalecane zamiast certyfikatów RSA ze względu na znacznie mniejszy rozmiar klucza oraz ich szybkość jednak to te drugie są częściej wykorzystywane ze względu na ich prostotę oraz są łatwiejsze do wdrożenia, co jest ich ogromną zaletą. Myślę, że minimalna konfiguracja to ECDSA (256-bit, P-256) lub RSA (2048-bit).

Kolejny przykład. Spójrz na następujące wyjaśnienie dla szyfru TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:

PROTOCOL KEY EXCHANGE AUTHENTICATION ENCRYPTION HASHING
TLS ECDHE ECDSA AES_128_GCM SHA256

TLS to protokół (standardowy punkt początkowy). Dzięki ECDHE możemy zobaczyć, że podczas uścisku dłoni klucze będą wymieniane za pomocą efemerycznej (klucze tymczasowe) wersji wymiany kluczy Diffie-Hellman z wykorzystaniem krzywej eliptycznej.

ECDSA to algorytm uwierzytelniania używany do podpisywania parametrów wymiany kluczy, pominięty w przypadku RSA. AES_128_GCM jest algorytmem szyfrowania zbiorczego: AES działający w trybie licznika Galois z kluczem 128-bitowym (nowoczesny tryb uwierzytelniania z powiązanymi danymi (AEAD), używany do zachowania poufności i integralności/autentyczności wiadomości, wykorzystujący 128-bitowe bloki). AES_256 oznaczałoby 256-bitowy klucz, w przypadku GCM możliwe są tylko AES, CAMELLIA i ARIA, przy czym AES jest zdecydowanie najbardziej popularnym i szeroko stosowanym wyborem (jest implementowany sprzętowo).

Wreszcie SHA-256 jest algorytmem mieszającym — funkcją skrótu używaną jako podstawa do wyprowadzenia klucza z głównego klucza tajnego w protokole TLS, a także do uwierzytelnienia gotowej wiadomości.

Jak już wspomniałem na wstępie, klient i serwer negocjują, który pakiet szyfrów ma być używany na początku połączenia TLS (klient wysyła listę obsługiwanych pakietów szyfrów, a serwer wybiera jeden i informuje klienta, jakiego wyboru dokonał). Wybór krzywej eliptycznej dla ECDH/ECDHE nie jest częścią kodowania zestawu szyfrów. Krzywa jest negocjowana osobno (tutaj również klient proponuje i serwer decyduje).

Ok, spójrz na ostatni przykład z wyjaśnieniem różnic między TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 i TLS_RSA_WITH_AES_128_GCM_SHA256.

Różnią się metodą wymiany kluczy. Pierwszy z nich używa efemerycznej krzywej eliptycznej DH do wymiany kluczy, zapewniając funkcję PFS. Ponieważ parametry są efemeryczne, są one odrzucane po użyciu, a wymienionego klucza nie można odzyskać. Z drugiej strony TLS_RSA_WITH_AES_128_GCM_SHA256 używa RSA w certyfikacie serwera do wymiany kluczy. Jest to nadal silne szyfrowanie (przy założeniu wystarczająco dużych kluczy), ale wymieniony klucz sesji można odzyskać ze strumienia za pomocą klucza prywatnego serwera.

Jeśli chcesz uzyskać wiele przydatnych informacji o dostępnych szyfrach oraz ich statusie, polecam ciekawą wyszukiwarkę: TLS Cipher Suite Search. Aby uzyskać więcej informacji, zapoznaj się również z dokumentem cipher suite definitions zestawiającym wszystkie (znakomitą większość) dostępne zestawy szyfrów.

Polecam także świetny artykuł Cipher Suites: Ciphers, Algorithms and Negotiating Security Settings oraz równie dobrą odpowiedź na temat roli wybranego zestawu szyfrów w połączeniu TLS.

Authenticated encryption (AEAD) #

Algorytmy AEAD są zazwyczaj dostarczane z dowodem bezpieczeństwa. Zapewniają wyspecjalizowane tryby działania szyfrów blokowych zwane trybami szyfrowania uwierzytelnionego (AE) lub czasami szyfrowania uwierzytelnionego z powiązanymi danymi (AEAD). Tryby te obsługują zarówno szyfrowanie, jak i uwierzytelnianie za jednym razem, zwykle za pomocą jednego klucza (połączenie szyfrowania i sprawdzania integralności w jednym algorytmie).

Te dowody bezpieczeństwa są oczywiście zależne od podstawowych prymitywów, ale daje to jednak więcej zaufania do pełnego schematu. Szyfry AEAD — niezależnie od wewnętrznej struktury — powinny być odporne na problemy spowodowane uwierzytelnianiem, a następnie szyfrowaniem (zerknij na How to choose an Authenticated Encryption mode).

Tryby AE(AD) zostały opracowane w celu ułatwienia implementacji problemu uwierzytelnienia. Co więcej, niektóre z tych trybów są bardzo szybkie. Dodatkowe zalety takich szyfrów to:

Każdy szyfr z funkcją skrótu, która jak wspomniałem, służy do zapewnienia integralności wiadomości, tj. GCM, CCM, czy POLY1305 jest szyfrem AEAD. Na przykład:

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CCM
TLS_ECDHE_ECDSA_WITH_AES_256_CCM
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_RSA_WITH_AES_128_CCM
TLS_DHE_RSA_WITH_AES_256_CCM
TLS_DHE_RSA_WITH_AES_128_CCM_8
TLS_DHE_RSA_WITH_AES_256_CCM_8
TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384

Jednak tylko poniższe szyfry są zalecane:

NAME ALIAS KEY SIZE SALT SIZE NONCE SIZE TAG SIZE
AEAD_CHACHA20_POLY1305 chacha20-ietf-poly1305 32 32 12 16
AEAD_AES_256_GCM aes-256-gcm 32 32 12 16
AEAD_AES_192_GCM aes-192-gcm 24 24 12 16
AEAD_AES_128_GCM aes-128-gcm 16 16 12 16

Co więcej, każdy z tych szyfrów chroni przed atakiem typu ROBOT.

W takim razie, jakie szyfry wybrać? #

Dla większego bezpieczeństwa używaj tylko silnych i nienarażonych na szwank pakietów szyfrów. Umieść zestawy ECDHE+AESGCM oraz DHE na górze listy (także jeśli martwisz się o wydajność priorytetowo ustaw ECDHE-ECDSA i ECDHE-RSA zamiast DHE — na przykład Chrome będzie traktować priorytetowo szyfry oparte na ECDHE przed szyframi opartymi na DHE).

DHE jest ogólnie wolny i co istotne, dla TLSv1.2 i niższych jest wrażliwy na słabe grupy (mniej niż 2048 bitów w tej chwili). Co więcej, nie określono żadnych ograniczeń dotyczących używania grup, jednak zalecane jest wykorzystanie ich predefiniowanych wersji opisanych w RFC 7919 - Supported Groups Registry [IETF] w celu zachowania zgodności z normami NIST oraz FIPS. Te problemy nie wpływają oczywiście na ECDHE, dlatego dziś zestawy szyfrów, które go wykorzystują, są ogólnie preferowane.

Zgodnie z analizą Alexa Top 1 Million Security Analysis, ponad 92,8% stron internetowych korzystających z szyfrowania woli używać szyfrów opartych na ECDHE. Natomiast według wyszukiwarki Shodan wykorzystanie szyfrów rozkłada się następująco:

Kolejność jest ważna, ponieważ zestawy ECDHE są szybsze. Co więcej, zalecane są efemeryczne wersje tj. DHE/ECDHE, które obsługują Perfect Forward Secrecy (metodę niemającą bezpośredniego powiązania z kluczem prywatnym serwera, która nie ma podatności na rodzaj ataku powtórkowego). Wydajność ECDHE-ECDSA jest mniej więcej taka sama jak RSA, ale znacznie bezpieczniejsza. ECDHE z RSA działa wolniej, ale nadal jest znacznie bezpieczniejszy niż sam RSA.

Serwery wykorzystują najbardziej preferowane oprogramowanie szyfrujące klienta lub konfigurację według własnych preferencji. Wyłączenie DHE usuwa kompatybilność wsteczną, ale skutkuje znacznie szybszym czasem uzgadniania.

Myślę, że dopóki kontrolujesz tylko jedną stronę konwersacji, niedorzeczne byłoby ograniczenie twojego systemu do obsługi tylko jednego zestawu szyfrów (zablokowałoby to zbyt wielu klientów i zbyt duży ruch). Z drugiej strony spójrz, co powiedział o tym David Benjamin (inżynier Google zajmujący się przeglądarką Chrome):

Servers should also disable DHE ciphers. Even if ECDHE is preferred, merely supporting a weak group leaves DHE-capable clients vulnerable.

Obecnie większość przeglądarek nie obsługuje już szyfrów DHE, które mogą przydać się jedynie dla specyficznych klientów łączących się do Twoich systemów. Dlatego przed ich włączeniem powinieneś dokonać dokładnej analizy i odpowiedzieć sobie na pytanie, czy faktycznie te szyfry są potrzebne.

W przypadku TLSv1.2 należy rozważyć wyłączenie słabych szyfrów (czyli takich, które nie wykorzystują PFS), takich jak szyfry z algorytmem CBC. Tryb CBC jest podatny na ataki w TLSv1.0, SSLv3.0 i niższych. Jednak prawdziwa poprawka jest zaimplementowana w TLSv1.2, w którym wprowadzono tryb GCM i który nie jest podatny na atak BEAST. Moim zdaniem powinieneś używać szyfrów z szyfrowaniem AEAD (TLS 1.3 obsługuje tylko te pakiety), ponieważ nie mają żadnych znanych słabości.

Należy również bezwzględnie wyłączyć słabe i niebezpieczne szyfry niezależnie od używanej wersji TLS, takie jak DSS, DSA, DES/3DES, RC4, MD5, SHA1 czy null (lub po prostu w ogóle ich nie dotykać i włączyć tylko bezpieczne i zalecane szyfry).

Jeżeli masz dylematy, mamy ciekawe narzędzia online do testowania kompatybilności zestawów szyfrów: CryptCheck - User agent compatibility oraz CryptCheck - Supported cipher suites. W razie wątpliwości użyj jednego z zalecanych zestawów Mozilli.

Szyfry a TLSv1.3 #

Nowa wersja protokołu TLS wprowadza mnóstwo ciekawych i ważnych zmian. Dotyczą one oczywiście także zestawu szyfrów.

W TLSv1.3 szyfrowanie i uwierzytelnianie zostały połączone w jeden element, wyeliminowano obsługę przestarzałych algorytmów i szyfrów (np. szyfrów blokowych), wyeliminowano obsługę wymiany kluczy RSA i narzucono wykorzystanie tylko szyfrów obsługujących funkcję PFS. Dodatkowo zmniejszono liczbę algorytmów w zestawach szyfrów do dwóch, włączono obsługę dodatkowych krzywych eliptycznych, a także wyeliminowano wszystkie szyfry pracujące w trybie blokowym, zastępując je szyfrowaniem AEAD.

Polecam te dwa dokumenty, jeżeli chcesz uzyskać więcej informacji o samym TLSv1.3 i zmianach, jakie wprowadza:

Jedną z ciekawszych zmian, jeżeli chodzi o zestawy szyfrów, jest to, że w TLSv1.3 nie zawierają one algorytmów wymiany kluczy i podpisów cyfrowych. Od teraz zawierają tylko algorytm mieszający i szyfry zbiorcze (ang. bulk cihpers), czyli symetryczne algorytmy szyfrowania używane do szyfrowania i deszyfrowania dużych ilości danych.

Ilość szyfrów zredukowano maksymalnie jak tylko się dało, w wyniku czego dostępnych jest tylko pięć szyfrów, z których de facto wykorzystać można trzy:

# Rekomendowane i stosowane:
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256

# Domyślnie wyłączone i przeznaczone dla urządzeń o niskiej mocy obliczeniowej:
TLS_AES_128_CCM_8_SHA256
TLS_AES_128_CCM_SHA256

Jeżeli chodzi o serwer NGINX, to obecnie nie mamy możliwości sterowania pakietami szyfrów z jego poziomu w celu korzystania z nowego API (większość aplikacji musi się jeszcze dostosować). NGINX nie jest w stanie na to wpłynąć, więc w tej chwili wszystkie dostępne szyfry są zawsze włączone (także jeśli wyłączysz potencjalnie słaby szyfr w NGINX). Z drugiej strony, szyfry w TLSv1.3 zostały ograniczone do garstki całkowicie bezpiecznych szyfrów przez głównych ekspertów w dziedzinie kryptografii.

Mozilla zaleca pozostawienie domyślnych szyfrów dla TLSv1.3 i niejawne włączanie ich w konfiguracji, ponieważ TLSv1.3 nie wymaga żadnych szczególnych zmian. Dlatego wszystkie połączenia TLSv1.3 będą używać następujących szyfrów w tej kolejności: AES-256-GCM, ChaCha20, a następnie AES-128-GCM. Zalecam właśnie taki sposób rozwiązania sprawy (poleganie na bibliotece), ponieważ dla TLSv1.3 zestawy szyfrów są stałe, więc ich ustawienie nie będzie miało tak naprawdę wpływu (automatycznie użyjesz tych trzech szyfrów, chyba że aplikacja je wyraźnie zdefiniuje jeśli ma taką możliwość).

Jeśli chcesz użyć szyfrów TLS_AES_128_CCM_SHA256 i TLS_AES_128_CCM_8_SHA256 (na przykład w systemach wbudowanych, które zwykle mają ograniczone wszystko), np. na wypadek, gdyby jakikolwiek z Twoich systemów wymagał ich obsługi w przyszłości, powinieneś zajrzeć do pliku openssl-1.1.1*/include/openssl/ssl.h i znaleźć poniższy fragment kodu:

#  if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
#   define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
                                    "TLS_CHACHA20_POLY1305_SHA256:" \
                                    "TLS_AES_128_GCM_SHA256"
#  else
#   define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
                                    "TLS_AES_128_GCM_SHA256"
#  endif
# endif

Po znalezieniu zmodyfikuj obie instrukcje #define, aby wyglądały jak poniżej (dodaj TLS_AES_128_CCM_SHA256 i TLS_AES_128_CCM_8_SHA256) i uważaj na dwukropki, cudzysłowy i znaki końca linii:

# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
#  define TLS_DEFAULT_CIPHERSUITES "TLS_AES_128_GCM_SHA256:" \
                                   "TLS_AES_128_CCM_SHA256:" \
                                   "TLS_AES_128_CCM_8_SHA256:" \
                                   "TLS_CHACHA20_POLY1305_SHA256:" \
                                   "TLS_AES_256_GCM_SHA384"
# else

/* We're definitely building with ChaCha20-Poly1305,
   so the "else" won't have any effect. Still... */
#  define TLS_DEFAULT_CIPHERSUITES "TLS_AES_128_GCM_SHA256:" \
                                   "TLS_AES_256_GCM_SHA384"

#endif

Pamiętaj jednak: GCM należy uznać za lepszy od CCM w przypadku większości aplikacji wymagających uwierzytelnionego szyfrowania.

Potencjalne problemy #

Jednym z głównych problemów, z którym możesz się spotkać, to starsze wersje klientów. Dlatego w celu zapewnienia kompatybilności wstecznej pomyśl o mniej restrykcyjnych szyfrach. Dobrze w takiej sytuacji jest zbadać ruch, jaki wpada na Twoje serwery i na tej podstawie wyodrębnić tylko te szyfry wykorzystywane przez klientów.

Inną ciekawą sprawą jest to, że nowoczesne zestawy szyfrów (np. te z rekomendacji Mozilli) cierpią z powodu problemów ze zgodnością głównie dlatego, że pozbywają się funkcji hashującej SHA-1 (zobacz na artykuł Gradually sunsetting SHA-1). Bądź jednak ostrożny jeśli chcesz używać szyfrów z HMAC-SHA-1, ponieważ udowodniono, że są one podatne na ataki kolizyjne. Należy rozważyć bezpieczniejsze alternatywy, takie jak SHA-256 lub SHA-3. Tutaj znajduje się doskonałe wytłumaczenie dlaczego.

Co jednak istotne, nie tylko musisz włączyć co najmniej jeden specjalny szyfr AES128 dla obsługi HTTP/2 w odniesieniu do RFC 7540 - TLS 1.2 Cipher Suites [IETF], ale musisz także zezwolić na krzywe eliptyczne prime256, co zmniejsza wynik skanera SSL Labs dla wymiany kluczy o kolejne 10% nawet jeśli ustawiona jest preferowana kolejność bezpiecznego serwera.

Jeśli chcesz uzyskać ocenę A+ oraz 100% dla Cipher Strength skanera SSL Labs, zdecydowanie powinieneś wyłączyć 128-bitowe (moim zdaniem to główny powód, dla którego nie powinieneś ich używać) zestawy szyfrów oraz szyfry CBC, które mają wiele słabych stron. Moim zdaniem 128-bitowe szyfrowanie symetryczne nie jest mniej bezpieczne. Co więcej, jest około 30% szybsze i nadal bezpieczne. Na przykład TLSv1.3 używa zestawu TLS_AES_128_GCM_SHA256 (0x1301).

Jedną z ciekawostek są zalecenia branżowe dotyczące kodu uwierzytelnienia wiadomości CHACHA20_POLY1305:

Jeżeli zależy Ci na zachowaniu zgodności z wytycznymi HIPAA i NIST SP 800-38D [PDF] powinieneś wyłączyć te zestawy szyfrów. Jest to jednak dla mnie niezrozumiałe i nie znalazłem racjonalnego wyjaśnienia, dlaczego powinniśmy to robić. ChaCha20 jest prostszy niż AES i obecnie jest znacznie szybszym algorytmem szyfrowania, jeśli nie jest dostępne przyspieszenie sprzętowe AES (w praktyce AES jest często implementowany w sprzęcie, co daje mu przewagę).

Co więcej, szybkość i bezpieczeństwo to prawdopodobnie powód, dla którego Google włączyło obsługę ChaCha20+Poly1305/AES w Chrome. Mozilla i Cloudflare także używają tych szyfrów w swoich konfiguracjach. Również IETF rekomenduje ich użycie.

Przykłady konfiguracji #

Zgodnie z tym co napisałem na początku tego wpisu, czyli, że zestawy szyfrów są jednym z najczęściej zmieniających się parametrów, pamiętaj o cyklicznej weryfikacji obecnych zaleceń czy standardów i dostosowaniu konfiguracji do aktualnych wytycznych.

Według mnie obecnie jednym z bezpieczniejszych zestawów przy włączonym TLSv1.3 oraz TLSv1.2 jest:

ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256";

Przy takiej konfiguracji pamiętaj o wykorzystaniu paremetrów DH o odpowiedniej długości min. 2048-bit (szyfry DHE).

Zestawy szyfrów dla TLSv1.3:

# Przykład konfiguracji dzięki której możliwe jest uzyskanie
# maksymalnej oceny. Nie trzeba wskazywać (w NGINX jest to niemożliwe)
# zestawów szyfrów dla TLSv1.3, ponieważ robi to za Nas biblioteka OpenSSL.
ssl_ciphers "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384";

Zestawy szyfrów dla TLSv1.2:

# Tylko szyfry ECDHE:
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384";

   » ssllabs score: 100%

Zestawy szyfrów dla TLSv1.3:

# Przykład konfiguracji dzięki której możliwe jest uzyskanie
# maksymalnej oceny. Nie trzeba wskazywać (w NGINX jest to niemożliwe)
# zestawów szyfrów dla TLSv1.3, ponieważ robi to za Nas biblioteka OpenSSL.
ssl_ciphers "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256";

Zestawy szyfrów dla TLSv1.2:

# 1)
# Wykorzystuje DHE (pamiętaj o parametrach DH o długości min. 2048-bit):
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256";

# 2)
# Tylko szyfry ECDHE (parametry DH nie są wymagane)
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";

# 3)
# Wykorzystuje DHE (pamiętaj o parametrach DH o długości min. 2048-bit):
ssl_ciphers "EECDH+CHACHA20:EDH+AESGCM:AES256+EECDH:AES256+EDH";

   » ssllabs score: 90%

Mozilla SSL Configuration Generator #

Poniżej znajduje się porównanie konfiguracji z przykładami znajdującymi się w Mozilla SSL Configuration Generator:

# Mozilla nie określa szyfrów dla TLSv1.3
# ssl_ciphers "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256";
# Mozilla nie określa szyfrów dla TLSv1.3
# ssl_ciphers "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256";
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

Rekomendowany zestaw zgodny z HIPAA i TLSv1.2+:

ssl_ciphers "TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-CCM:DHE-RSA-AES128-CCM:DHE-RSA-AES256-CCM8:DHE-RSA-AES128-CCM8:DH-RSA-AES256-GCM-SHA384:DH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA256";

Dodatkowe przykłady konfiguracji dla TLSv1.2 #

Moja rekomendacja (z pierwszego przykładu) #

ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256";
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH x25519 (eq. 3072 bits RSA)   FS 128
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)   DH 2048 bits   FS  256
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)   DH 2048 bits   FS  256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)   DH 2048 bits   FS  128
IE 11 / Win Phone 8.1  R  Server sent fatal alert: handshake_failure
Safari 6 / iOS 6.0.1  Server sent fatal alert: handshake_failure
Safari 7 / iOS 7.1  R Server sent fatal alert: handshake_failure
Safari 7 / OS X 10.9  R Server sent fatal alert: handshake_failure
Safari 8 / iOS 8.4  R Server sent fatal alert: handshake_failure
Safari 8 / OS X 10.10  R  Server sent fatal alert: handshake_failure
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256xccaa   DHE-RSA-CHACHA20-POLY1305         DH 2048    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 521   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

SSL Labs 100% #

ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384";
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
Android 5.0.0 Server sent fatal alert: handshake_failure
Android 6.0 Server sent fatal alert: handshake_failure
Firefox 31.3.0 ESR / Win 7  Server sent fatal alert: handshake_failure
IE 11 / Win 7  R  Server sent fatal alert: handshake_failure
IE 11 / Win 8.1  R  Server sent fatal alert: handshake_failure
IE 11 / Win Phone 8.1  R  Server sent fatal alert: handshake_failure
IE 11 / Win Phone 8.1 Update  R Server sent fatal alert: handshake_failure
Safari 6 / iOS 6.0.1  Server sent fatal alert: handshake_failure
Safari 7 / iOS 7.1  R Server sent fatal alert: handshake_failure
Safari 7 / OS X 10.9  R Server sent fatal alert: handshake_failure
Safari 8 / iOS 8.4  R Server sent fatal alert: handshake_failure
Safari 8 / OS X 10.10  R  Server sent fatal alert: handshake_failure
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

SSL Labs 90% (1) #

ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256";
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)   DH 2048 bits   FS  256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xccaa)   DH 2048 bits   FS  256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH x25519 (eq. 3072 bits RSA)   FS 128
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)   DH 2048 bits   FS  128
IE 11 / Win Phone 8.1  R  Server sent fatal alert: handshake_failure
Safari 6 / iOS 6.0.1  Server sent fatal alert: handshake_failure
Safari 7 / iOS 7.1  R Server sent fatal alert: handshake_failure
Safari 7 / OS X 10.9  R Server sent fatal alert: handshake_failure
Safari 8 / iOS 8.4  R Server sent fatal alert: handshake_failure
Safari 8 / OS X 10.10  R  Server sent fatal alert: handshake_failure
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256xccaa   DHE-RSA-CHACHA20-POLY1305         DH 2048    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 521   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

SSL Labs 90% (2) #

ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH x25519 (eq. 3072 bits RSA)   FS 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)   ECDH x25519 (eq. 3072 bits RSA)   FS   WEAK  256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)   ECDH x25519 (eq. 3072 bits RSA)   FS   WEAK  128
No errors
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384xc028   ECDHE-RSA-AES256-SHA384           ECDH 521   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 521   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256xc027   ECDHE-RSA-AES128-SHA256           ECDH 521   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

SSL Labs 90% (3) #

ssl_ciphers "EECDH+CHACHA20:EDH+AESGCM:AES256+EECDH:AES256+EDH";
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)   DH 2048 bits   FS  256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)   DH 2048 bits   FS  128
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)   ECDH x25519 (eq. 3072 bits RSA)   FS   WEAK  256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   ECDH x25519 (eq. 3072 bits RSA)   FS   WEAK 256
TLS_DHE_RSA_WITH_AES_256_CCM_8 (0xc0a3)   DH 2048 bits   FS 256
TLS_DHE_RSA_WITH_AES_256_CCM (0xc09f)   DH 2048 bits   FS 256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b)   DH 2048 bits   FS   WEAK 256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   DH 2048 bits   FS   WEAK  256
No errors.
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384xc028   ECDHE-RSA-AES256-SHA384           ECDH 521   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384xc014   ECDHE-RSA-AES256-SHA              ECDH 521   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHAx9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256xc0a3   DHE-RSA-AES256-CCM8               DH 2048    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8xc09f   DHE-RSA-AES256-CCM                DH 2048    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCMx6b     DHE-RSA-AES256-SHA256             DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256x39     DHE-RSA-AES256-SHA                DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHAx9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

Mozilla modern profile #

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH x25519 (eq. 3072 bits RSA)   FS 128
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH x25519 (eq. 3072 bits RSA)   FS 256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)   DH 2048 bits   FS  128
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)   DH 2048 bits   FS  256
IE 11 / Win Phone 8.1  R  Server sent fatal alert: handshake_failure
Safari 6 / iOS 6.0.1  Server sent fatal alert: handshake_failure
Safari 7 / iOS 7.1  R Server sent fatal alert: handshake_failure
Safari 7 / OS X 10.9  R Server sent fatal alert: handshake_failure
Safari 8 / iOS 8.4  R Server sent fatal alert: handshake_failure
Safari 8 / OS X 10.10  R  Server sent fatal alert: handshake_failure
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 521   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 521   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

Dodatkowe przykłady konfiguracji dla TLSv1.3 #

Mozilla modern profile (zalecany) #

TLS_AES_256_GCM_SHA384 (0x1302)   ECDH x25519 (eq. 3072 bits RSA)   FS  256
TLS_CHACHA20_POLY1305_SHA256 (0x1303)   ECDH x25519 (eq. 3072 bits RSA)   FS  256
TLS_AES_128_GCM_SHA256 (0x1301)   ECDH x25519 (eq. 3072 bits RSA)   FS  128
Chrome 69 / Win 7  R  Server sent fatal alert: protocol_version
Firefox 62 / Win 7  R Server sent fatal alert: protocol_version
OpenSSL 1.1.0k  R Server sent fatal alert: protocol_version
SSLv2SSLv3TLS 1TLS 1.1TLS 1.2TLS 1.3x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256

Dodatkowe zasoby #