Простой способом зашифровать данные, передаваемые по сети - это протоколы SSL и TLS. Они расположены на уровне представления (presentation) данных, на 6-ом уровне модели протокола TCP / IP, что позволяет без проблем использовать их для прикладных протоколов 7го уровня (HTTP, WebSocket, ...).
SSL / TLS используют комбинацию технологий симметричного и асимметричного шифрования. На этапе установления соединения (handshake) используется асимметричное шифрование. Также, оно используется для проверки подлинности. Для передачи данных используется симметричное шифрование. TLS позволяет убедиться в целостности данных и аутентифицировать отправителя.
Преимущества SSL / TLS:
Симметричное шифрование имеет преимущество в скорости перед ассиметричным, поэтому именно оно используется в SSL / TLS для шифрования трафика.
Протокол Диффи-Хеллмана позволяет клиенту и серверу сгенерировать симметричные ключи шифрования через открытый канал связи.
Идея протокола Диффи-Хеллмана:
Клиент и сервер генерируют собственные (локальные) секреты. Для алгоритма используется однонаправленная функция для которой легко вычислить значение и проблематично вычислить аргументы по значению. Клиент и сервер передают по открытому каналу друг другу значения функции от секретных аргументов. Проводят над этими значениями и аргументами собственные вычисления и, в результате применения некоторых преобразований, могут прийти к одному и тому же значению.
Перехват промежуточных значений и знание алгоритма без локального секрета не даст возможности восстановить результат.
Важно: В процессе установления соединения клиент (как и сервер) может передать ключ шифрования и с использованием ассиметричного шифрования. Такая возможность есть. Но это не безопасный способ обменяться симметричными ключами, так как при компрометации приватного ключа ассиметричного алгоритма - становится возможным расшифровать сообщение содержащее ключ шифрования трафика. Протокол Диффи-Хеллмана решает проблему создания сессионного ключа через открытый канал связи.
SSL (Secure Sockets Layer) - протокол передачи данных, обеспечивающий шифрование, защиту и аутентификацию.
Не будем останавливаться на нем подробно, так как его можно считать устаревшим начиная с 1999 года, когда появился TLS 1.0. В настоящее время, если кто-то говорит про SSL, то это, скорее всего, TLS. Часто используется термин SSL для обозначения сертификатов TLS.
SSL был медленным и менее безопасным чем современный TLS. На этапе установления соединения требовал больше активности между клиентом и сервером. Содержал не стойкие алгоритмы шифрования.
TLS – прямой преемник SSL.
Основная цель TLS заключалась в том, чтобы сделать SSL более безопасным, а спецификации протокола более точными и полными.
TLS предполагает, что между узлами установлено надёжное соединение, протокол не поддерживает повторную отправку потерянных пакетов данных. Но существует DTLS для работы в условиях негарантированной доставки.
Отличия TLS от SSL:
TLS 1.0 и TLS 1.1 - уже устаревшие версии TLS.
не следует доверять TLS и связанным технологиям свою жизнь или жизнь других людей
TLS-сертификат - это важнейший компонент в TLS.
Сертификат содержит открытый ключ сервера для сервера и открытый ключ клиента для клиента. Дополнительно к публичному ключу в сертификат включается подпись, сделанная промежуточным сертификатом (приватным ключом) выше уровня. Они используются на этапе установления соединения, чтобы проверить подлинность друг друга и безопасно обменяться ключами для дальнейшей работы.
В TLS возможна обоюдная (двухсторонняя) аутентификация узлов, использующая TLS-сертификаты.
Сервер может указать клиенту имена удостоверяющих центров, ключи которых сервер будет использовать для проверки клиентского сертификата.
Цепочка сертификатов - это несколько TLS-сертификатов, среди которых один серверный сертификат, один "корневой сертификат" и "промежуточные сертификаты".
Серверный сертификат - это сертификат, который по имени соответствует серверу и содержит серверный открытый ключ электронной подписи (в большинстве случаев - RSA или ECDSA).
Корневые сертификаты - это сертификат удостоверяющего центра.
Сервер или клиент может предоставить цепочку сертификатов, каждый из них подписан вышестоящим центром:
"сертификат сервера" --подписан в X-->
"промежуточные сертификаты X" --подписан в Y-->
"промежуточные сертификаты Y" --подписан Z-->
"корневой сертификат Z"
Правильные/валидные подписи сертификатов всей цепочки подтверждают подлинность сертификата сервера.
Рукопожатие (handshake) - это самый важный этап, который следует сразу за tcp handshake. В процессе рукопожатия клиент и сервер договариваются об используемых шифрах, методах аутентификации и симметричных ключах шифрования.
Практически сразу, еще до окончания рукопожатия клиент и сервер переходят на зашифрованный обмен:
Если рассматривать этот процесс не углубляясь в детали, то мы имеем:
1. выработка начального значения общего криптографического секрета
Клиент передает на сервер приветствие, настройки сессии и секрет (handshake_traffic_secret) для генерации набор симметричных ключей (для клиента и сервера), которые будут использоваться для шифрования сообщений рукопожатия.
2. определение параметров соединения
Сервер передает клиенту настройки сессии (ServerHello). Это последнее сообщение, которое передается без шифрования. Далее весь обмен будет зашифрован.
В зашифрованном виде сервер передает клиенты свою цепочку сертификатов и если требуется, то запрос клиентского сертификата.
Важно: ответ сервера зашифрован с помощью набор симметричных ключей сгенерированного на основе handshake_traffic_secret и предыдущих сообщений.
Важно: так как ответ сервера зашифрован, то нельзя узнать какой сертификат сервер передал клиенту и передал ли его вообще.
3. аутентификация (сервера и клиента)
Последним этапом клиент и сервер удостоверяются что собеседник является тем за кого себя выдает.
Симметричные ключи генерируются по протоколу Диффи-Хеллмана на основе локального секрета, сообщений которые были переданы до момента создания ключа и handshake_traffic_secret.
В TLS 1.3 используются симметричные ключи разных уровней для разных этапов: handshake, трафик и т.п. Каждый следующий ключ вычисляется на основе предыдущего ключа и дополнительных данных.
Полная схема установки соединения для TLS 1.3:
Client Server
Key ^ ClientHello
Exch | + key_share*
| + signature_algorithms*
| + psk_key_exchange_modes*
v + pre_shared_key* -------->
ServerHello ^ Key
+ key_share* | Exch
+ pre_shared_key* v
{EncryptedExtensions} ^ Server
{CertificateRequest*} v Params
{Certificate*} ^
{CertificateVerify*} | Auth
{Finished} v
<-------- [Application Data*]
^ {Certificate*}
Auth | {CertificateVerify*}
v {Finished} -------->
[Application Data] <-------> [Application Data]
здесь:
'*' необязательные сообщения (передаются в зависимости от контекста)
фигурные скобки - сообщения Handshake. передаются в зашифрованном виде
квадратные скобки - данные полезной нагрузки. передаются в зашифрованном виде, но с использованием другого набора ключей шифрования.
TLS 1.3 позволяет реализовать обоюдную (двухсторонную) аутентификацию. Для этого сервер передает CertificateRequest, сообщая клиенту, что он должен предоставить сертификат для проверки. CertificateVerify - подписанное клиентом сообщение. Проверив подпись по сертификату клиента (публичному ключу) можно убедиться, что клиент обладает приватной частью ключа.
Сокращённая схема предусмотрена для уменьшения потери времени на установление соединения.
0-RTT (Zero Round-Trip Time) - нулевая задержка приёма-передачи.
Работает только если клиент и сервер уже имеют общий секрет. Имея общий секрет, клиент отправляет его на первом этапе (п.1 см. выше) вместе с остальными данными и сразу (до ответа сервера) передает данные приложения. Сервер отвечает (п.2 см. выше) и сразу передает ответ приложения.
Такой подход вносит минимальные задержки, но менее безопасен.
Из-за того, что клиент должен хранит общий секрет, то при компрометации общего секрета первый запрос клиент к серверу может быть расшифрован. Стоит отметить, что ответ сервера и все остальные запросы и ответы будут шифроваться надежными ключами.
В сокращенной форме мы имеем потенциально уязвимую фазу первого обращения клиента к серверу. Данные приложения этой фазы (только то, что передается к серверу. http запрос) могут быть раскрыты.
Отсутствие ожидания первого ответа сервера должно ускорить обмен данными.
TLS 1.2 (полный вариант) и TLS 1.3 (полный вариант):
Для версии TLS 1.2 существует сокращённый сценарий рукопожатия для экономии ресурсов.
Суть заключается в том, что в процессе рукопожатия сервер передает клиенту SessionID (идентификатор новой сессии). Этот идентификатор может быть использован клиентом позже для быстрого установления (восстановления) сессии. На стороне сервера и клиента хранится всё, что необходимо для быстрого восстановления сессии.
Современные браузеры активно используют эту функцию.
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
Установление соединения по сокращённой схеме
Источник: RFC 5246
Transport Layer Security (TLS) Session Resumption without Server-Side State позволяет восстанавливать сессии и избежать хранения сессии для каждого клиента.
Сервер формирует состояние сессии в так называемый тикет (TLS Session Ticket), шифрует его и передает клиенту. Клиент может хранить тикет сессии и избежать рукопожатия с созданием сессии передав тикет обратно серверу. Такой подход позволяет избежать траты вычислительных ресурсов на проверку подписи и генерацию секретов в процессе рукопожатия.
Datagram Transport Layer Security (DTLS) - сетевой протокол, предназначенный для безопасной передачи данных с использованием UDP.
Подходит для потоковой передачи, медиа-протоколов, протоколов IP-телефонии.
В протоколе используются:
Формат записи DTLS
struct {
ContentType type;
ProtocolVersion version;
uint16 epoch; // New field
uint48 sequence_number; // New field
uint16 length;
opaque fragment[DTLSPlaintext.length];
} DTLSPlaintext;
Рукопожатия реализовано аналогично протоколу TLS со следующими отличиями:
Mutual Transport Layer Security (mTLS) — Взаимная защита транспортного уровня.
Строго говоря, это не протокол, а соглашение или подход, который позволяет реализовать двухсторонную аутентификацию (см. выше), используя функцию TLS протокола.
В TLS, обычно, клиент проверяет сертификат сервера и аутентифицирует его. Но в протоколе TLS у сервера есть опциональная возможно запросить сертификат клиента. Сервер может отказать клиенту в обслуживании если его сертификат не пройдет проверку.
mTLS - это TLS с обязательным использованием двухсторонней аутентификации и сертификатами для клиента и сервера.
mTLS широко используется в Service Mesh решениях для организации аутентификации сервисов между собой.
Проблемы, которые приносит с собой mTLS:
ГОСТ TLS - это спецификация, которая определяет криптонаборы с российскими алгоритмами хэширования, шифрования и электронной подписи для протоколов TLS 1.2 и TLS 1.3 (алгоритмамы Магма и Кузнечик из ГОСТ Р 34.12-2015). Это делает протокол TLS не совместимым с мировыми стандартами без дополнительных инструментов. Заявляется, что использование российскими криптоалгоритмов повышает защищенность.
Российские криптографические алгоритмы:
ГОСТ 28147-89
ГОСТ Р 34.10-94
ГОСТ Р 34.11-94
ГОСТ Р 34.10-2012
Разработчики: КриптоПро. Они предлагают разные инструменты как для серверных решений (например TLS-шлюз КриптоПро NGate), так и для клиентских.
CryptoPro TLS-CA - удостоверяющий центр.
It Is Time to Redesign Transport Layer Security
What Is a Message Authentication Code (MAC)?
Что такое модель OSI и зачем она нужна: препарируем слоёный пирог интернета
Ключи, шифры, сообщения: как работает TLS
Что такое TLS-рукопожатие и как оно устроено
ГОСТ TLS cертификаты для вашего домена
Transport Layer Security
The Transport Layer Security (TLS) Protocol Version 1.3
The Transport Layer Security (TLS) Protocol Version 1.2
The Secure Sockets Layer (SSL) Protocol Version 3.0
RFC 8996 Deprecating TLS 1.0 and TLS 1.1
КРАТКОЕ ОПИСАНИЕ DTLS ПРОТОКОЛА
Datagram Transport Layer Security
Что такое Mtls и как оно работает?