---
# System prepended metadata

title: Прокотолы TLS/SSL
tags: [сети]

---

---
tags: сети
---
# Прокотолы TLS/SSL

## Протоколы TLS/SSL в модели TCP/IP и OSI

TLS и SSL - это семейство протоколов для обеспечения безопасности передачи данных в интернет.
- TLS (Transport Layer Security) - протокол защиты транспортного уровня
- SSL (Secure Socket Layer) - уровень защищенных сокетов (устарел)

Назначение протоколов - обеспечение безопасной передачи данных в небезопасной сети. Эти протоколы используются в других протоколах прикладного уровня для безопасности, например HTTPS, SMTPS, POP3S и другие.

В модели TCP/UP TLS расположен в транспортном уровне:
![](https://i.imgur.com/uofXZRu.png)

В модели OSI TLS примерно соответствует трем уровням, так как включает функции со всех трех:
![](https://i.imgur.com/AluA6sb.png)

Протокол TLS обеспечивает:

1) Приватность данных - данные, передаваемые по сети шифруются, чтобы посторонний не мог их прочитать
2) Целостность данных - данные защищены от постороннего вмешательства и изменения (с помощью контрольной суммы/хэша)
3) Аутентификация - защита от атаки типа Man in the middle, подтверждение личности (цифровая подпись, инфраструктура открытых ключей)

### Шифрование в TLS/SSL

В TLS используются оба типа шифрования (симметричное, ассиметричное) для того, чтобы компенсировать недостатки обоих.
* Ассиметричное шифрование для передачи ключа симметричного шифрования
* Симметричное шифрование для передачи данных

**Алгоритм обмена ключами RSA**
![](https://i.imgur.com/8RaVNb1.png)
1) Клиент шлет серверу сообщение "Hello", говорящее о том, что он хочет начать шифрованную сессию
2) Сервер в ответ отсылает клиенту свой открытый ключ
3) Клиент получая открытый ключ генерирует ключ, который будет использоваться для симметричного шифрования, зашифровывает этот ключ с помошью открытого ключа, пришедшего от сервера и отправляет
4) Сервер расшифровывает ключ для симметричного шифрования своим приватным ключом и использует в дальнейшем его

**Недостатки такого алгоритма:**

- Не обеспечивается совершенная полная секретность (Perfect Forward secrecy), доступ к закрытому ключу сервера позволит расшифровать все передаваемые данные
- Уязвимости RSA (Bleichenbacher million message attack, ROBOT)

Поэтому алгоритм RSA запрещено использовать начиная с TLS 1.3

Вместо RSA используется **алгоритм Диффи-Хеллмана**

![](https://i.imgur.com/97T6DKM.png)
*Зеленым обозначены числа, которые можно передавать в открытом виде, красным - приватные*
1) Перед обменом данными клиент и сервер договариваются о двух числах, которые они будут совместно использовать для шифрования,
**p** = 29 и **g** = 3
3) Далее клиент и сервер генерируют два числа, которые будут использоваться для того, чтобы генерировать ключ симметричного шифрования (**5** и **8**)
4) Клиент выполняет операцию $3^5$ mod 29 = 11 и отправляет это число серверу
5) Сервер выполняет похожий расчет, используя свое число 8: 
$3^8$ mod 29 = 7, передает это число клиенту
6) Клиент получив число сервера снова выполняет ту же операцию на этом числе: $7^5$ mod 29 = 16 и получает ключ для симметричного шифрования
7) Сервер делает то же самое с числом 11 от клиента. Итог - ключ для сессии шифрования равен 16

Такой результат получается благодаря коммутативному свойству операции взятия по модулю - сервер и клиент выполняют одни и те же операции в разном порядке и получают одинаковый результат.

Условия работы алгоритма Диффи-Хеллмана: 
* p - большое простое число, минимум 1024 бита
* g - первообразный корень по модулю p, небольшое целое число

При соблюдении этих условий ключ невозможно вычислть даже на современных суперкомпьютерах, и раскодировать полученные данные невозможно даже при получении доступа к серверу.

### Целостность данных в TLS/SSL

Для подтверждения целостности и неизмененности данных в TLS используются криптографические хэш-функции (MD5, SHA)

Клиент по данным рассчитывает хэш, включает результат в пакет и передает серверу. Сервер извлекает данные, рассчитывает хэш и сравнивает с значением хэша из пакета.

В TLS для защиты от постороннего вмешательства в данные в значение хэша считается не только на основе данных, но также на значении разделяемого ключа, который есть только у клиента и сервера. Поле, контролирующее это называется MAC (Message Authentication Code). Злоумышленник, даже если перехватит данные, не сможет сгенерировать MAC, так как у него нет ключа для его генерации.

### Аутентификация в TLS/SSL

Для защиты от атаки посредника в TLS используются технологии электронной подписи и структуры открытых ключей.

Электронная подпись использует ассиметричное шифрование. В этом случае сообщение шифруется закрытым ключом и может быть расшифрованно открытым. Это используется для подтверждения, что именно обладатель закрытого ключа зашифровал это сообщение, и никто другой. В TLS сервер таким образом шифрует хэш и отправляет клиенту. Клиент, получив подпись, расшифровывает ее с помощью открытого ключа, который он получил от сервера и получает хэш. После с помощью криптографической функции клиент извлекает хэш из данных и сравнивает с хэшем, полученным из подписи.

Однако злоумышленник может подменить открытый ключ сервера. Для предотвращения этого используется инфраструктура открытых ключей. Она предполагает, что сеть состоит из узлов, которые изначально не доверяют друг другу, но все они доверяют одному узлу, называемому удостоверящим центром. Удостоверяющий центр выдает узлам сертификаты - файлы специального вида, содержащие некоторые компоненты (в главную очередь открытый ключ шифрования для сервера) и зашифрованный **открытым ключом центра сертификации**. Сервер вместе с данными передает свой сертификат, который расшифровывается клиентом открытым ключом центра сертификации, который ему известен, и если расшифровать удалось, клиент доверяет серверу.

Из-за масштабов интернета сертификационные центры могут не справляться с количеством сертификатов, поэтому они могут быть организованы в иерархию сертификационных центров
![](https://i.imgur.com/iHt9Bh5.png)

Сервер получает сертификат от удост. центра, а сертификат удост. центра получен от корневого удост. центра
Пример: hackmd
![](https://i.imgur.com/znU40So.png)

Последнее, что остается подтвердить - сертификат корневого сертификационного центра. Технического решения, которое бы позволяло решить эту проблему гарантированно, нет, но в операционных системах при установке записываются некоторые сертификаты корневых центров.

Также, сертификаты могут быть самоподписанными - такие сертификаты подписано закрытым ключом сервера. В таком случае нельзя быть уверенным, что он не был подменен. НО: сертификаты всех корневых центров как раз самоподписаны.

**Итого:**

Алгоритмы шифрования в TLS/SSL:
![](https://i.imgur.com/8oIuGGF.png)

## Протокол TLS

TLS состоит из нескольких протоколов
![](https://i.imgur.com/idqpM9V.png)

**1) Протокол записей** (Record protocol) - основа TLS. В записи record вкладываются сообщения вышестоящих протоколов TLS, алгоритмы шифрования и целостности работают на уровне записей, сообщения протокола записей вкладываются в сегменты TCP. 
Формат сообщения протокола записи:
![](https://i.imgur.com/lueZlB9.png)
Тип сообщения говорит о том, какой вышестоящий проткол TLS используется, далее указывается версия протокола, длина сообщения.
**2) Протокол установки соединения** 
>Для передачи данных по TLS необходимо установить так называемую сессию TLS, клиенту и серверу необходимо договориться о том, какой  набор шифров они будут использовать, обменяться разделяемыми ключами для симметричного шифрования и ключом для MAC. Все операции обмена ключами занимают долгое время, поэтому в TLS предусмотрен механизм возобновления сессии, если клиент ранее подключался к серверу и они уже договаривались о ключах, то они могут просто возобновить сессию и использовать эти ключи.
Передача данных в TLS когда сессия установлена: у сервера и клиента есть все ключи и они договорились об алгоритмах шифрования в рамках сессии

1) Клиент получает от вышестоящего протокола данные
2) Протокол, содержащийся в TLS разбивает эти данные на отдельные фрагменты-сообщения
3) Перед отправкой клиент создает МАС и присоединяет к сообщению
4) С помощью симметричного ключа сообщение вместе с МАС шифруется и передается по сети
5) Сервер принимает зашифрованное сообщение и расшифровывает сообщение с помощью симм. ключа
6) Затем сервер считает МАС и сравнивает с тем что был получен в сообщении
7) Если все прошло успешно, то сообщение записывается в буфер сервера. Далее так же с остальными сообщениями, которые в итоге объединяются в данные и передаются в вышестоящий протокол

**3) Протокол оповещений**
Сообщает об ошибках в работe TLS. Есть два типа сообщений:
- Фатальные ошибки (сессия TLS должна быть разорвана немедленно)
  - Ошибка MAC (bad_record_mac)
  - Неизвестный удостоверяющий центр (unknown_ca)
  - Ошибка расшифровки (decrypt_error)
- Предупреждения (сессия может продолжать работать)
    - Срок действия сертификата истек (Certificate_expired)
    - Сертификат отозван (certificate_revoked)
    - Неизвестный формат сертификата (unsupported_certificate)

### Установка соединения TLS

Возьмем набор шифров TLS:
* Обмен ключами - Диффи-Хеллман
* Цифровая подпись - RSA
* Симметричное шифрование - AES
* Хэш-функция для MAC - SHA-256

**1)** Клиент отправляет сообщение Client hello, в это сообщение включается перечень шифров и случайное простое число client random для алг. Диффи-Хеллмана
**2)** Получив сообщение Client hello сервер отправляет Server hello, в который также включаются случайное число server random, выбранный сервером шифр TLS и идентификатор сессии
**3)** В следующем сообщении, отправляемом серверу находится сертификат сервера
**4)** Клиент, получив сертификат, проверяет его: 
    - Проверка цифровых подписи удост. центров
    - Проверка "доверяия корневому удост. центру
    - Проверка домена сертификата
    - Проверка срока действия
    - Проверка, не отозван ли сертификат
 **5)** Затем, если используется алгоритм diffie-hellman ephemeral, числа p, g передаются в отдельном сообщении (если исп. обычный DH, то они находятся в сертификате)
**6)** После всех этих сообщений сервер передает сообщение Hello Done, означающее, что сервер передал все, что нужно для первой фазы установки соединения и клиенту можно больше ничего не ждать от сервера
**7)** На следующем этапе выполняется процедура обмена ключами - клиент передает серверу информацию, необходимую для генерации разделяемого ключа. 
* Если используется алгоритм **RSA**, то по открытому ключу клиент шифрует сгенерированный pre-master-secret и передает его серверу. Сервер использует свой закрытый ключ для расшифровки и получает pre-master secret, на основе которого далее обе стороны рассчитывают разделяемый ключ.
* Если используется **DH**, то клиент в сообщении client key exchange передает значение $Y_c$, которое рассчитано на основе чисел p и g, полученных от сервера. Затем клиент и сервер на основе полученной информации проводят расчеты и получают значение pre-master secret


**8)** Для рассчета разделяемого ключа и ключа MAC в TLS используется псевдослучайная функция, которая генерирует ключ для сессии на основе seed, в качестве которого используется pre-master secret. Сервер и клиент таким образом получают эти ключи, которые в дальнейшем будут использоваться для переключения на симметричное шифрования. 
**9)** Клиент шлет сообщение Change Cipher Spec (это является частью отдельного протокола change cipher protocol), которое говорит о том, что клиент готов использовать симметричное шифрование и ключи, которыми клиент и сервер обменялсь.
**10)** После этого клиент отправляет сообщение Finished, первое сообщение, зашифрованное симметричным шифрованием и защищено MAC
**11)** Сервер, получив эти два сообщения, если все в порядке, также передает клиенту сообщения change cipher cpec и Finished и соединение считается установленным.

### Разрыв соединения 

После окончания передачи данных для разрыва соединения используется alert сообщение close_notify. При отправке такого сообщение (от клиента или от сервера) получатель должен отправить такое же сообщение и прекратить передачу данных. Такой разрыв - двусторонний, в отличие от TCP.
![](https://i.imgur.com/B9dIFOh.png)


### Восстановление сессии TLS

Если клиент и сервер в недавнем прошлом уже устанавливали сессию TLS и договаривались о ключах, то при отправке сообщения Client hello клиент может включить идентификатор сессии, которую он хочет восстановить, и если сервер находит в своей таблице такую сессию, то он высылает подряд Server hello, Change Cipher Spec и Finished, без других действий. Клиент получает сообщение finished, расшифровывает и проверяет MAC, и если все в порядке, также шлет Change Cipher Spec и Finished, и соединение считается установленным.
![](https://i.imgur.com/pAKrKBd.png)

