Всем привет, этот пост начинает серию статей о криптографических протоколах. Перед тем как начать его читать, рекомендую ознакомиться с предыдущей статьей.
TLS(Transport Layer Security) – криптографический протокол, основанный на протоколе SSL(Secure Sockets Layer), обеспечивающий, защищённую от прослушивания и подмены, передачу данных между узлами в сети интернет. Основной целью являлось получение относительно безопасного канала для осуществления покупок или управления банковским счётом. В современном интернете на TLS полагаются не только в коммерческой деятельности, но и при решении гораздо более общей задачи сохранения приватности информации. В основе криптобезопасности протокола лежат задачи: сокрытия информации, обнаружения модификации данных, проверки авторства, которые обеспечивают конфиденциальность, целостность и подлинность соединения(аутентификацию) соответственно. При использовании TLS, злоумышленнику будет доступна информация о подключении(хост, порт, тип используемого шифрования), частоте и количестве передаваемой информации. Кроме того, он может разорвать соединение, но обе стороны будут знать, что соединение было прервано третьей стороной.
В различных источниках TLS может быть расположен на различных уровнях модели OSI, что может вызвать непонимание. Нужно учитывать, что модель OSI – это концептуальная конструкция, которая пытается описать сетевую реальность. В действительности TLS состоит из двух протоколов: один работает внизу сеансового уровня(handshake, change cipher spec, alert), а другой работает наверху транспортного уровня(record layer). С технической точки зрения TLS работает на транспортном уровне. Это позволяет более высокоуровневым протоколам(HTTP, FTP, SMTP) работать без изменений.
HIGH-LEVEL DESCRIPTION
После установления TCP-соединения и перед тем, как начать обмен по протоколу TLS, клиент и сервер должны согласовать некоторые параметры: версию протокола, шифронабор, а так же проверить сертификаты. Основные шаги процедуры создания защищённого сеанса связи:
1. Установление TCP-соединения.
2. Клиент предоставляет версию протокола и список поддерживаемых шифронаборов.
3. Сервер утверждает версию используемого протокола и выбирает из списка, предоставленного клиентом, наиболее надёжные шифронаборы среди тех, которые поддерживаются сервером, прикрепляет свой сертификат и отправляет ответ клиенту(при желании сервер может запросить клиентский сертификат).
4. Клиент, до начала передачи данных, проверяет валидность(аутентичность) полученного серверного сертификата и инициирует обмен ключами по протоколу Диффи-Хеллмана. Существует исторический метод передачи сгенерированного клиентом секрета на сервер, при помощи шифрования асимметричной криптосистемой RSA(используется ключ из сертификата сервера).
5. После установления общего секрета сервер обрабатывает присланное клиентом сообщение, сверяет MAC, и отправляет клиенту заключительное сообщение в зашифрованном виде.
6. Клиент расшифровывает полученное сообщение, сверяет MAC.
После этого соединение считается установленным и начинается обмен данными. При возникновении проблем на некоторых из вышеуказанных шагов подтверждение связи может завершиться с ошибкой, а безопасное соединение будет разорвано.
LOW-LEVEL DESCRIPTION
Чтобы установить контекст соединения клиент и сервер должны обменяться handshake-сообщениями. В TLS такой обмен происходит поверх обмена записями(records). Несколько handshake-сообщений могут быть переданы в одной записи(самый распространённый случай) или одно сообщение может быть разбито на несколько записей, передаваемых последовательно(теоретический вариант). Каждое handshake-сообщение содержит специальный заголовок, состоящий из четырёх байт. Первый байт обозначает код типа сообщения, три следующих байта – длину сообщения.
Спецификация предполагает, что клиент и сервер уже согласовали шифронабор null, без MAC и без сжатия. Это значит, что клиент и сервер будут обмениваться сообщениями в виде открытого текста без аутентификации.
Процесс установки безопасного соединения.
- Версию протокола – максимальную версию, которую готов поддерживать клиент.
- 32 байта случайных данных – Client Random. Изначально, в спецификации рекомендовалось использовать первые 4 байта для передачи UNIX-timestamp, а оставшиеся 28 – заполнять результатом работы криптографического генератора псевдослучайных чисел.
- Идентификатор TLS-сессии – SessionID. В случае если клиент хочет возобновить ранее установленную сессию.
- Список шифронаборов, которые поддерживает клиент – Cipher Suites. Порядок шифронаборов в списке отражает их степень предпочтения клиентом(предпочтительные передаются первыми).
- Список поддерживаемых методов сжатия – Compression Methods. Обычно в этом поле лишь одно значение – null.
- Данные о расширениях протокола.
- Версию протокола, которую будут использовать клиент и сервер.
- 32 байта случайных данных – Server Random.
- Идентификатор сессии – SessionID для текущего соединения.
- Выбранный сервером шифронабор(cipher suite) из предложенных клиентом.
- Выбранный сервером метод сжатия, скорее всего это null.
- Данные о расширениях протокола.
- Типы сертификатов, которые поддерживает сервер.
- Список пар хэш-функия/алгоритм подписи, которыми сервер в состоянии проверить подпись на сертификате клиента.
- Список имен удостоверяющих центров, ключи которых сервер будет использовать для проверки клиентского сертификата.
- Определяется количество байт, нужное для выбранного шифронабора.
- Получаем необходимое количество байт(key block).
- Полученный key block разбивается на несколько частей, клиентские: ключ для вычисления MAC, ключ для шифрования, вектор инициализации, и серверные: ключ для вычисления MAC, ключ для шифрования, вектор инициализации.
ClientHello
Первым сообщением из цепочки handshake-сообщений всегда является ClientHello(0x01). Сообщение содержит в себе:
struct { ProtocolVersion client_version; Random random; SessionID session_id; CipherSuite cipher_suites<2..2^16-2>; CompressionMethod compression_methods<1..2^8-1>; select (extensions_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ClientHello;
Шифронабор это 16-битный идентификатор устанавливающий набор криптографических примитивов. Например, шифронабор TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 имеет идентификатор 0xc02b. Это означает, что для обмена ключами используется протокол Диффи-Хеллмана на эллиптических кривых с эфемерными ключами, в качестве алгоритма цифровой подписи выступает DSA на эллиптических кривых, AES c 256-битным ключом в режиме GCM в качестве симметричного блочного шифра в режиме аутентифицированного шифрования, SHA384 в качестве хэш-функции.
Разберем ClientHello в деталях. В качестве сервера используем этот блог. В качестве сниффера небезызвестный Wireshark.
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Client Hello 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2, что по сути SSL 3.3. 00 dc Length: 220 - длина пакета данных 220 байт. Handshake Protocol: Client Hello 01 Handshake Type: Client Hello (1) - первый байт сообщения TLS тип 01, сообщение ClientHello. 00 00 d8 Length: 216 - длина блока данных 216 байт. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. Random - 32 байта случайных значений, ClientRandom, состоит из 4 байт unix-timestamp и 28 байт случайных данных. 58 a9 f9 5f GMT Unix Time: Feb 19, 2017 23:00:31.000000000 RTZ 2 (зима) b5 60 3a c0 ... Random Bytes: b5603ac065209230b7704d848ad766c627af0a8d051f3a8661666911 00 Session ID Length: 0 - длина поля SessionID так, как SessionID в данном сообщении не используется его длинна составляет 0 байт. 00 38 Cipher Suites Length: 56 - длина поля со списком шифронаборов. Cipher Suites (28 suites) - в данном случае указано 28 шифронаборов, по два байта на каждый из них. c0 2c Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) c0 2b Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) c0 30 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) c0 2f Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 00 9f Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f) 00 9e Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e) c0 24 Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024) c0 23 Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023) c0 28 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) c0 27 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027) c0 0a Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) c0 09 Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) c0 14 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) c0 13 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) 00 39 Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039) 00 33 Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033) 00 9d Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) 00 9c Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c) 00 3d Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d) 00 3c Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c) 00 35 Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035) 00 2f Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f) 00 0a Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a) 00 6a Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006a) 00 40 Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040) 00 38 Cipher Suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038) 00 32 Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032) 00 13 Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013) 01 Compression Methods Length: 1 - длина поля методов сжатия. 00 Compression Methods (1 method) - 00 - null, клиент не поддерживает сжатие. 00 77 Extensions Length: 119 - длина поля расширений, далее следует список расширений клиента Extension: server_name Extension: status_request Extension: elliptic_curves Extension: ec_point_formats Extension: signature_algorithms Extension: SessionTicket TLS Extension: Application Layer Protocol Negotiation Extension: Extended Master Secret Extension: Unknown 21760 Extension: renegotiation_info
После отправки сообщения ClientHello клиент ждет сообщение ServerHello. Любое handshake-сообщение кроме ServerHello должно расцениваться как фатальная ошибка.
ServerHello
Если сервер успешно обработал ClientHello, то он должен ответить ServerHello в котором содержатся следующие данные:
struct { ProtocolVersion server_version; Random random; SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; select (extensions_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ServerHello;
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Server Hello 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 00 50 Length: 80 - длина пакета данных 80 байт. Handshake Protocol: Server Hello 02 Handshake Type: Server Hello (2) - первый байт сообщения TLS тип 02, сообщение ServerHello. 00 00 4c Length: 76 - длина блока данных 216 байт. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. Random - 32 байта случайных значений, ServerRandom, состоит из 4 байт unix-timestamp и 28 байт случайных данных. 6a 31 50 83 GMT Unix Time: Jun 16, 2026 16:32:51.000000000 RTZ 2 (зима) f6 30 f3 d4 ... Random Bytes: f630f3d49eeb979daaa31031ca9de723bc0f939bedda727eb647f227 00 Session ID Length: 0 - длина поля SessionID так, как SessionID в данном сообщении не используется его длинна составляет 0 байт. c0 30 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) - выбранный сервером шифронабор. 00 Compression Method: null (0) - выбранный алгоритм сжатия. 00 24 Extensions Length: 36 - длина поля расширений, далее следует список расширений сервера. Extension: server_name Extension: renegotiation_info Extension: ec_point_formats Extension: SessionTicket TLS Extension: Application Layer Protocol Negotiation
Параметры переданные в Hello-соообщениях позволяют построить контекст для работы криптосистемы, которая будет обрабатывать защищённые TLS-записи на стороне сервера и клиента. Помимо ClientHello и ServerHello, установление соединения подразумевает обмен несколькими другими сообщениями. За отправкой ServerHello, со стороны сервера следует ряд других сообщений, состав и содержание этих сообщений зависят от выбранного сервером режима работы.
Certificate
Серверный сертификат, который содержит открытый ключ сервера. Это сообщение отправляется всегда, за исключением случаев, когда шифронабор предписывает handshake без сертификата(анонимный режим). В большинстве случаев клиенту будет передана цепочка сертификатов(certificate chain), для того, чтобы клиент смог построить цепочку доверия от сертификата сервера до корневого сертификата.
struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate;
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Certificate 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 09 c7 Length: 2503 - длина пакета данных 2503 байт. Handshake Protocol: Certificate 0b Handshake Type: Certificate (11) - первый байт сообщения TLS тип 11, сообщение Certificate. 00 09 c3 Length: 2499 - длина блока данных 2499 байт. 00 09 c0 Certificates Length: 2496 - длина блока сертификатов. Certificates (2496 bytes) 00 05 24 Certificate Length: 1316 - длина данных первого сертификата. 30 82 05 20 30 ... Certificate: 3082052030820408a003020102021203e8f9d8f7071bc196... (id-at-commonName=cyberdeveloper.pro) 00 04 96 Certificate Length: 1174 - длина данных первого сертификата. 30 82 04 92 30 ... Certificate: 308204923082037aa00302010202100a0141420000015385... (id-at-commonName=Let's Encrypt Authority X3,id-at-organizationName=Let's Encrypt,id-at-countryName=US)
В данном сообщении сервер прислал нам два сертификата, первый сертификат принадлежит серверу, второй центру сертификации(Certificate Authority — CA). Клиент должен произвести ряд проверок для всей цепочки, таких как, проверку подписи, проверку имени и убедиться, что сертификат не отозван.
ServerKeyExchange
Это сообщение содержит дополнительные значения необходимые для генерации общего симметричного ключа. Оно опционально и его наличие зависит от выбранного шифронабора. В нем могут быть, параметры протокола Диффи-Хеллмана. В нашем случае на эллиптических кривых(ECDHE) – идентификатор кривой и открытый ключ. Параметры подписываются сервером с помощью выбранного алгоритма(RSA в нашем случае), клиент может проверить подпись, используя открытый ключ сервера из сертификата. Так как DH не защищен от модификации параметров, подпись позволяет убедиться, что их никто не подменил.
enum { dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa /* may be extended, e.g., for ECDH -- see [TLSECC] */ } KeyExchangeAlgorithm; struct { opaque dh_p<1..2^16-1>; opaque dh_g<1..2^16-1>; opaque dh_Ys<1..2^16-1>; } ServerDHParams; /* Ephemeral DH parameters */ struct { select (KeyExchangeAlgorithm) { case dh_anon: ServerDHParams params; case dhe_dss: case dhe_rsa: ServerDHParams params; digitally-signed struct { opaque client_random[32]; opaque server_random[32]; ServerDHParams params; } signed_params; case rsa: case dh_dss: case dh_rsa: struct {} ; /* may be extended, e.g., for ECDH -- see [TLSECC] */ }; } ServerKeyExchange;
Из структуры сообщения видно, что подпись вычисляется для случайных данных клиента, случайных данных сервера и параметров протокола Диффи-Хеллмана.
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 01 4d Length: 333 - длина пакета данных 333 байт. Handshake Protocol: Server Key Exchange 0c Handshake Type: Server Key Exchange (12) - первый байт сообщения TLS тип 12, сообщение ServerKeyExchange. 00 01 49 Length: 329 - длина блока данных 329 байт. EC Diffie-Hellman Server Params 03 Curve Type: named_curve (0x03) - тип эллиптической кривой. 00 17 Named Curve: secp256r1 (0x0017) - название эллиптической кривой. 41 Pubkey Length: 65 - длина публичного ключа 65 байт. 04 d5 1f a4 32 ... Pubkey: 04d51fa432ea48fd4b0a6eb637eb9ca094cf435db5fa414b... - публичный ключ. Signature Hash Algorithm: 0x0401 04 Signature Hash Algorithm Hash: SHA256 (4) - используемая хэш-функция. 01 Signature Hash Algorithm Signature: RSA (1) - используемый алгоритм подписи. 01 00 Signature Length: 256 - длина цифровой подписи 256 байт. 01 8d 6b 4e 22 ... Signature: 018d6b4e22890292aba68596385948f1cec6f899b7a256e3... - значение подписи.
CertificateRequest
В TLS возможна двухсторонняя аутентификация. Сервер может запросить клиентский сертификат отослав сообщения CertificateRequest. Сообщение содержит:
struct { ClientCertificateType certificate_types<1..2^8-1>; SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; DistinguishedName certificate_authorities<0..2^16-1>; } CertificateRequest;
При подключении к этому блогу сервер не стал запрашивать у нас сертификат(что очевидно), поэтому мы остались без пакета. Некоторые следующие сообщения будут так же рассмотрены только для ознакомления.
ServerHelloDone
Это сообщение флаг нулевой длинны, которое посылается сервером, чтобы указать на то, что сервер закончил передавать свою часть данных для обмена ключами.
struct { } ServerHelloDone;
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 00 04 Length: 4 - длина пакета данных 4 байта. Handshake Protocol: Server Hello Done 0e Handshake Type: Server Hello Done (14) - первый байт сообщения TLS тип 14, сообщение ServerHelloDone. 00 00 00 Length: 0 - длина блока данных 0 байт.
После отправки этого сообщения, сервер должен ожидать ответа от клиента.
Certificate
Это сообщение посылается только если сервер запрашивал сертификат. Если у клиента нет подходящего сертификата, он должен ответить сообщением не содержащим сертификаты. Структура сообщения точно такая же, как у серверного сообщения Certificate.
struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate;
Если клиент не посылает никаких сертификатов или в процессе проверки произошли ошибки, сервер может по своему усмотрению, либо продолжить без аутентификации клиента, либо среагировать летальным оповещением(handshake failure alert).
ClientKeyExchange
Это сообщение клиент должен посылать всегда. С помощью этого сообщения будет установлен общий симметричный ключ, путем передачи секрета(premaster secret) зашифрованного публичным ключом сервера, или путем передачи параметров протокола Диффи-Хеллмана, которые позволят каждой из сторон согласовать общий секрет.
struct { ProtocolVersion client_version; opaque random[46]; } PreMasterSecret; struct { select (PublicValueEncoding) { case implicit: struct { }; case explicit: opaque dh_Yc<1..2^16-1>; } dh_public; } ClientDiffieHellmanPublic; struct { select (KeyExchangeAlgorithm) { case rsa: EncryptedPreMasterSecret; case dhe_dss: case dhe_rsa: case dh_dss: case dh_rsa: case dh_anon: ClientDiffieHellmanPublic; } exchange_keys; } ClientKeyExchange;
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 00 46 Length: 70 - длина пакета данных 70 байт. Handshake Protocol: Client Key Exchange 10 Handshake Type: Client Key Exchange (16) - первый байт сообщения TLS тип 16, сообщение ClientKeyExchange. 00 00 42 Length: 66 - длина блока данных 0 байт. EC Diffie-Hellman Client Params 41 Pubkey Length: 65 - длина публичного ключа 65 байт. 04 8d 5f 95 a4 ... Pubkey: 048d5f95a4b75ae51b1b534181581ed36cfed4550032b992... - публичный ключ.
Публичный ключ Диффи-Хеллмана генерируется клиентом в соответствии с параметрами, переданными сервером в сообщении ServerKeyExchange. Серверные параметры Диффи-Хеллмана подписываются приватным ключом сервера, клиент проверяет подпись, используя публичный ключ сервера.
CertificateVerify
Данное сообщение передается только если был передан клиентский сертификат в сообщении Certificate. Оно содержит цифровую подпись всех переданных ранее handshake-сообщений. Такая подпись доказывает факт наличия приватного ключа, связанного с сертификатом, у клиента.
struct { digitally-signed struct { opaque handshake_messages[handshake_messages_length]; } } CertificateVerify;
На этом этапе фаза переговоров считается законченной. Клиент и сервер имеют одинаковую последовательность байт(premaster secret) из которой они должны вычислить общий секрет(master secret).
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random);
Здесь PRF – псевдослучайная функция, в TLS 1.2 построена на базе хеш-функции SHA-256, либо может быть использована более мощная хеш-функция, указанная в составе шифронабора. Общий секрет(master secret) всегда равен 48 байтам, в отличие от premaster secret, размер которого может меняться в зависимости от метода обмена ключами. На основе общего секрета(master secret) будет сгенерированы остальные необходимые для сессии ключи, с использованием той же псевдослучайной функции. Делается это следующим способом:
key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random + SecurityParameters.client_random);
ChangeCipherSpec
Это сообщение посылается как клиентом, так и сервером и предназначено для уведомления принимающей стороны о том, что последующие записи(records) будут защищены в соответствии с выбранным шифронабором. Это сообщение не является handshake-сообщением и поэтому имеет тип 20, а не 22.
struct { enum { change_cipher_spec(1), (255) } type; } ChangeCipherSpec;
Secure Sockets Layer TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec 14 Content Type: Change Cipher Spec (20) - первый байт заголовка TLS-записи тип 20, сообщение ChangeCipherSpec. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 00 01 Length: 1 - длина пакета данных 4 байта. 01 Change Cipher Spec Message - первый байт сообщения TLS тип 1, сообщение ChangeCipherSpec.
Finished
Последнее в блоке handshake-сообщений и первое зашифрованное сообщение. Также посылается обеими сторонами сразу за ChangeCipherSpec. Необходимо для подтверждения того, что клиент и сервер согласовали эти параметры именно друг с другом.
Клиентское Finished-сообщение содержит хэш и MAC от всех предыдущих handshake-сообщений отправленных обеими сторонами. Серверное также содержит хэш и MAC от предыдущих сообщений, включая клиентское Finished.
struct { opaque verify_data[verify_data_length]; } Finished;
verify_data = PRF(master_secret, finished_label, Hash(handshake_messages));
Получатель этого сообщения должен расшифровать сообщение, проверить MAC и вычислить хэш от сообщений, которые он сохранил, и сравнить их с тем, что пришло в сообщении. Совпадение хэшей означает, что параметры соединения не были подменены третьей стороной.
Secure Sockets Layer TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message 16 Content Type: Handshake (22) - первый байт заголовка TLS-записи тип 22, сообщение handshake. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 00 28 Length: 40 - длина зашифрованных данных 40 байт. 10 8b f1 82 ... Handshake Protocol: Encrypted Handshake Message - зашифрованная часть данных.
После обмена узлами ChangeCipherSpec и Finished, защищенное соединение считается установленным и начинается обмен данными(Application Data).
ApplicationData
Данные этого сообщения зашифрованы, защищены MAC-кодом для предотвращения атак повторного воспроизведения(replay attack) и модификации данных. MAC вычисляется от MAC-ключа(полученного из key block), порядкового номера сообщения, длинны сообщения, содержания сообщения и двух константных строк. Включение порядкового номера в MAC, позволяет обнаружить попытки удалить сообщения или изменить их порядок.
Secure Sockets Layer TLSv1.2 Record Layer: Application Data Protocol: http-over-tls 17 Content Type: Application Data (23) - первый байт заголовка TLS-записи тип 23, сообщение ApplicationData. 03 03 Version: TLS 1.2 (0x0303) - версия TLS 1.2. 04 54 Length: 1108 - длина зашифрованных данных 1108 байт. 6c dd ... Encrypted Application Data: 6cddbe5287c45ddf97681ecdebff12ed0e910b1e80eb4d2d... - зашифрованная часть данных.
Соединение остаётся открытым до тех пор, пока одна из сторон не отправит сообщение, предупреждающее о завершении(close notify).
Alert
Еще один из типов сообщений поддерживаемых TLS-записями. Эти сообщения содержат уровень серьезности и описание предупреждения.
enum { warning(1), fatal(2), (255) } AlertLevel; enum { close_notify(0), unexpected_message(10), bad_record_mac(20), decryption_failed_RESERVED(21), record_overflow(22), decompression_failure(30), handshake_failure(40), no_certificate_RESERVED(41), bad_certificate(42), unsupported_certificate(43), certificate_revoked(44), certificate_expired(45), certificate_unknown(46), illegal_parameter(47), unknown_ca(48), access_denied(49), decode_error(50), decrypt_error(51), export_restriction_RESERVED(60), protocol_version(70), insufficient_security(71), internal_error(80), user_canceled(90), no_renegotiation(100), unsupported_extension(110), (255) } AlertDescription; struct { AlertLevel level; AlertDescription description; } Alert;
Пример: если клиент обнаружил, что сертификат сервера отозван, он отправляет сообщение Alert, содержащим ошибку certificate_revoked. Предупреждения с уровнем fatal сообщают о немедленном прекращении сеанса. Узлы должны стереть данные связанные с текущим подключением. Данные сообщения отправляются в открытом виде до установки защищенного соединения, а после в зашифрованном.
РЕЗЮМЕ
В данной статье мы рассмотрели основные сообщения протокола TLS, а так же разобрались, что они из себя представляют и для чего служат. Стоит отметить, что сейчас в разработке TLS 1.3, в котором будут некоторые изменения, но для понимания работы протокола возможные нововведения не критичны.
ПОЛЕЗНЫЕ ССЫЛКИ:
RFC-5246 – The Transport Layer Security (TLS) Protocol Version 1.2.
How does SSL/TLS work – хорошие ответы на security stackexchange.
Ключи, шифры, сообщения: как работает TLS – большое описание протокола на русском.
Первые несколько миллисекунд HTTPS соединения – статья с хабра раз.
Что такое TLS – статья с хабра два.
Если вам нравятся мои статьи, можете следить за обновлениями с помощью E-Mail, Twitter, Facebook, а также канала в Telegram.