Протоколы защищенных каналов. часть 3. SSL

Один из подходов к решению проблемы безопасности в Интернете был предложен компанией Netscape Communications. Ею был разработан протокол SSL (Secure Sockets Layer) защищенного обмена информацией между клиентом и сервером. SSL требует применения надежного транспортного протокола (например, TCP).

Протокол SSL предназначен для решения традиционных задач обеспечения защиты информационного взаимодействия, которые в среде клиент/сервер интерпретируются следующим образом:
— пользователь, подключаясь к серверу, должен быть уверен, что он обменивается информацией не с подставным сервером, а именно с тем, который ему нужен (в противном случае это может привести к курьезным, если не к печальным, последствиям). Во многих приложениях необходимо также, чтобы и сервер мог надежно идентифицировать клиента, не ограничиваясь защитой паролем;
— после установления соединения между сервером и клиентом весь информационный поток между ними должен быть защищен от несанкционированного доступа;
— при обмене информацией стороны должны быть уверены в отсутствии случайных или умышленных искажений при ее передаче.

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

Конфиденциальность информации, передаваемой по установленному защищенному соединению, обеспечивается путем шифрования потока данных на сформированном общем ключе с использованием симметричных криптографических алгоритмов (например, RC4_128, RC4_40, RC2_128, RC2_40, DES40 и др.), а контроль целостности передаваемых блоков данных - за счет использования так называемых кодов аутентификации сообщений (Message Autentification Code, MAC), вычисляемых с помощью хеш-функций (в частности, MD5).

Протокол SSL включает в себя два этапа взаимодействия сторон защищаемого соединения:
— установление SSL-сессии;
— защита потока данных.

На этапе установления SSL-сессии осуществляется аутентификация сервера и (опционально) клиента, стороны договариваются об используемых криптографических алгоритмах и формируют общий "секрет", на основе которого создаются общие сеансовые ключи для последующей защиты соединения. Этот этап называют также процедурой "рукопожатия".
На втором этапе (защита потока данных) информационные сообщения прикладного уровня нарезаются на блоки, для каждого блока вычисляется код аутентификации сообщений, затем данные шифруются и отправляются приемной стороне. Приемная сторона производит обратные действия: дешифрование, проверку кода аутентификации сообщения, сборку сообщений, передачу на прикладной уровень.

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

Протокол SSL предоставляет "безопасный канал", который имеет три основные свойства:
1. канал является частным (шифрование используется для всех сообщений после простого диалога, который служит для определения секретного ключа);
2. канал аутентифицирован (серверная сторона диалога всегда аутентифицируется, в то время как клиентская аутентифицируется опционно);
3. канал надежен (транспортировка сообщений включает в себя проверку целостности).

формат заголовка записи SSL

В SSL все данные пересылаются в виде records (записей) — объектов, которые состоят из заголовка и некоторого количества данных. Каждый заголовок записи содержит два или три байта кода длины. Если старший бит в первом байте кода длины запси равен 1, тогда запись не имеет заполнителя и полная длина заголовка равна 2 байтам, в противном случае запись содержит заполнитель и полная длина заголовка равна 3 байтам. Передача всегда начинается с заголовка.
Заметим, что в случае длинного заголовка (3 байта), второй по старшинству бит первого байта имеет специальное значение. Когда он равен нулю, посылаемая запись является информационной. При равенстве 1, посылаемая запись является security escape (в настоящее время не определено ни одного значения security escapes; оно зарезервировано для будущих версий протокола).
Код длины записи не включает в себя число байт заголовка (2 или 3). Для 2-байтового заголовка его длина вычисляется следующим образом (используется Си-подобная нотация):

RECORLENGTH = ((byte[0] & 0x7F << 8)) | byte[1];

где byte[0] представляет собой первый полученный байт, а byte[1] — второй полученный байт. Когда используется 3-байтовый заголовок, длина записи вычисляется следующим образом:

RECORD-LENGTH = ((byte[0] & 0x3F) << 8)) | byte[1];
IS-ESCAPE = (byte[0] & 0x40) != 0;
PADDING = byte[2];

Заголовок записи определяет значение, называемое PADDING. Значение PADDING специфицирует число байтов добавленных отправителем к исходной записи. Данные заполнителя используются для того, чтобы сделать длину записи кратной размеру блока шифра, если применен блочный шифр.

Отправитель "заполненной" записи добавляет заполнитель после имеющихся данных, а затем шифрует все это, благо длина этого массива кратна размеру блока используемого шифра. Содержимое заполнителя не играет роли. Так как объем передаваемых данных известен, заголовок сообщения может быть корректно сформирован с учетом объема субполя PADDING.
Получатель этой записи дешифрует все поле данных и получает исходную информацию. После этого производится вычисление истинного значения RECORD-LENGTH (с учетом наличия опционного PADDING), при этом заполнитель из поля данные удаляется.

формат информационных записей SSL

Часть данных записи SSL состоит из трех компонентов (передаваемых и получаемых в приведенном ниже порядке):

MAC-DATA[MAC-SIZE]
ACTUAL-DATA[N]
PADDING-DATA[PADDING]

ACTUAL-DATA представляет собой реальные переданные данные (поле данных сообщения). PADDING-DATA — это данные заполнителя, посылаемые когда используется блочный код шифрования. MAC-DATA является кодом аутентификации сообщения (Message Authentication Code).
Когда записи SSL посылаются открытым текстом, никаких шифров не используется. Следовательно, длина PADDING-DATA будет равна нулю и объем MAC-DATA также будет нулевым. Когда используется шифрование, PADDING-DATA является функцией размера блока шифра. MAC-DATA зависит от CIPHER-CHOICE. MAC-DATA вычисляется следующим образом:

MAC-DATA = HASH[ SECRET, ACTUAL-DATA, PADDING-DATA, SEQUENCE-NUMBER ]

Где SECRET передается хэш-функции первым, далее следует ACTUAL-DATA и PADDING-DATA, за которыми передается SEQUENCE-NUMBER. Порядковый номер (SEQUENCE-NUMBER) представляет собой 32-битовый код, который передается хэш-функции в виде 4 байт. Первым передается старший байт (т.е., используется сетевой порядок передачи — "big endian").
MAC-SIZE является функцией используемого алгоритма вычисления дайджеста. Для MD2 и MD5 MAC-SIZE равен 16 байтам (128 битам).

Значение SECRET зависит оттого, кто из партнеров посылает сообщение. Если сообщение посылается клиентом, тогда SECRET равен CLIENT-WRITE-KEY (сервер будет использовать SERVER-READ-KEY для верификации MAC). Если клиент получает сообщение, SECRET равен CLIENT-READ-KEY (сервер будет использовать SERVER-WRITE-KEY для генерации MAC).
SEQUENCE-NUMBER является счетчиком, который инкрементируется как сервером, так и получателем. Для каждого направления передачи, используется пара счетчиков (один для отправителя, другой для получателя). При отправлении сообщения счетчик инкрементируется. Порядковыми номерами являются 32-битовые целые числа без знака, которые при переполнении обнуляются.

Получатель сообщения использует ожидаемое значение порядкового номера для передачи хэш-функции MAC (тип хэш-функции определяется параметром CIPHER-CHOICE). Вычисленная MAC-DATA должна совпадать с переданной MAC-DATA. Если сравнение не прошло, запись считается поврежденной, такая ситуация рассматривается как случай "I/O Error" (т.e. как непоправимая ошибка, которая вызывает закрытие соединения).

Окончательная проверка соответствия выполняется, когда используется блочный шифр и соответствующий протокол шифрования. Объем данных в записи (RECORD-LENGTH) должен быть кратным размеру блока шифра. Если полученная запись не кратна размеру блока шифра, запись считается поврежденной, при этом считается, что имела место "I/O Error" (что вызовет разрыв соединения).

Уровень записей SSL используется для всех коммуникаций SSL, включая сообщения диалога и информационный обмен. Уровень записей SSL применяется как клиентом, так и сервером.
Для двухбайтового заголовка максимальная длина записи равна 32767 байтов, для трехбайтового — 16383 байтов. Сообщения протокола диалога SSL должны соответствовать одиночным записям протокола SSL. Сообщения прикладного протокола могут занимать несколько записей SSL.

Прежде чем послать первую запись SSL все порядковые номера делаются равными нулю. При передаче сообщения порядковый номер инкрементируется, начиная с сообщений CLIENT-HELLO и SERVER-HELLO.

спецификация протокола диалога SSL

Протокол диалога SSL имеет две основные фазы. Первая фаза используется для установления конфиденциального канала коммуникаций. Вторая служит для аутентификации клиента.

фаза 1
Первая фаза является фазой инициализации соединения, когда оба партнера посылают сообщения "hello". Клиент инициирует диалог посылкой сообщения CLIENT-HELLO. Сервер получает сообщение CLIENT-HELLO, обрабатывает его и откликается сообщением SERVER-HELLO.

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

Когда нужен новый мастер-ключ, сообщение SERVER-HELLO будет содержать достаточно данных, чтобы клиент мог сформировать такой ключ. Сюда входит подписанный сертификат сервера, список базовых шифров, и идентификатор соединения (последний представляет собой случайное число, сформированное сервером и используемое на протяжении сессии). Клиент генерирует мастер-ключ и посылает сообщение CLIENT-MASTER-KEY (или сообщение ERROR, если информация сервера указывает, что клиент и сервер не могут согласовать базовый шифр).
Здесь следует заметить, что каждая оконечная точка SSL использует пару шифров для каждого соединения (т.е. всего 4 шифра). На каждой конечной точке, один шифр используется для исходящих коммуникаций и один — для входящих. Когда клиент или сервер генерирует ключ сессии, они в действительности формируют два ключа, SERVER-READ-KEY (известный также как CLIENT-WRITE-KEY) и SERVER-WRITE-KEY (известный также как CLIENT-READ-KEY). Мастер-ключ используется клиентом и сервером для генерации различных ключей сессий.
Наконец, после того как мастер-ключ определен, сервер посылает клиенту сообщение SERVER-VERIFY. Этот заключительный шаг аутентифицирует сервер, так как только сервер, который имеет соответствующий общедоступный ключ, может знать мастер-ключ.

фаза 2
Вторая фаза является фазой аутентификации. Сервер уже аутентифицирован клиентом на первой фазе, по этой причине здесь осуществляется аутентификация клиента. При типичном сценарии, серверу необходимо получить что-то от клиента, и он посылает запрос. Клиент пришлет позитивный отклик, если располагает необходимой информацией, или пришлет сообщение об ошибке, если нет. Эта спецификация протокола не определяет семантику сообщения ERROR, посылаемого в ответ на запрос сервера (например, конкретная реализация может игнорировать ошибку, закрыть соединение, и т.д. и, тем не менее, соответствовать данной спецификации). Когда один партнер выполнил аутентификацию другого партнера, он посылает сообщение finished. В случае клиента сообщение CLIENT-FINISHED содержит зашифрованную форму идентификатора CONNECTION-ID, которую должен верифицировать сервер. Если верификация терпит неудачу, сервер посылает сообщение ERROR.
Раз партнер послал сообщение finished он должен продолжить воспринимать сообщения до тех пор, пока не получит сообщение finished от партнера. Как только оба партнера послали и получили сообщения finished, протокол диалога SSL закончил свою работу. С этого момента начинает работать прикладной протокол.

типовой протокол обмена сообщениями

В несколько упрощенном варианте диалог SSL представлен на рис.1.

Рис.1. Алгоритм работы SSL

Ниже представлено несколько вариантов обмена сообщениями в рамках протокола диалога SSL. В этих примерах представлены два участника диалога: клиент (С) и сервер (S). Запись вида "{X}key" означает, что “X” зашифровано с помощью ключа "key".

Табл.1. Обмен сообщениями при отсутствии идентификатора сессии.

сlient-helloC > Schallenge, cipher_specs
server-helloS > Cconnection-id,server_certificate, cipher_specs
client-master-keyC > S{master_key}server_public_key
client-finishC > S{connection-id}client_write_key
server-verifyS > C{challenge}server_write_key
server-finishS > C{new_session_id}server_write_key

Табл.2. Обмен сообщениями в случае, когда идентификатор сессии найден клиентом и сервером.

сlient-helloC > Schallenge, session_id, cipher_specs
server-helloS > Cconnection-id, session_id_hit
client-finishC > S{connection-id}client_write_key
server-verifyS > C{challenge}server_write_key
server-finish S > C{session_id}server_write_key

Табл.3. Обмен сообщениями при использовании идентификатора сессии и аутентификации клиента.

сlient-helloC > Schallenge, session_id, cipher_specs
server-helloS > Cconnection-id, session_id_hit
client-finishC > S{connection-id}client_write_key
server-verifyS > C{challenge}server_write_key
request-certificateS > C{auth_type,challenge'}server_write_key
client-certificateC > S{cert_type,client_cert, response_data}client_write_key
server-finishS > C{session_id}server_write_key


В последнем обмене, response_data является функцией auth_type.

обработка ошибок

Обработка ошибок в протоколе соединений SSL весьма проста. Когда ошибка детектирована, обнаруживший его посылает своему партнеру сообщение. Ошибки, которые являются неустранимыми, требуют от клиента и сервера разрыва соединения. Серверы и клиент должны "забыть" все идентификаторы сессии, сопряженные с разорванным соединением. Протокол диалога SSL определяет следующие ошибки:

NO-CIPHER-ERROR. Эта ошибка присылается клиентом серверу, когда он не может найти шифр или размер ключа, который поддерживается также и сервером. Эта ошибка неустранима.
NO-CERTIFICATE-ERROR. Когда послано сообщение REQUEST-CERTIFICATE, эта ошибка может быть прислана, если клиент не имеет сертификата. Эта ошибка устранима.
BAD-CERTIFICATE-ERROR. Такой отклик присылается, когда сертификат по какой-то причине считается принимающей стороной плохим. Плохой означает, что, либо некорректна подпись сертификата, либо некорректно его значение (например, имя в сертификате не соответствует ожидаемому). Эта ошибка устранима (только для аутентификации клиента).
UNSUPPORTED-CERTIFICATE-TYPE-ERROR. Этот отклик присылается, когда клиент/сервер получает тип сертификата, который он не поддерживает. Эта ошибка устранима (только для аутентификации клиента).

сообщения протокола диалога SSL

Сообщения протокола диалога SSL инкапсулируются в записи протокола SSL и состоят из двух частей: однобайтового кода типа сообщения, и некоторых данных. Клиент и сервер обмениваются сообщениями, пока обе стороны не пошлют сообщения finished, указывающие, что они удовлетворены диалогом SSL (Handshake Protocol).
После того как каждый из партеров определил пару ключей сессии, тела сообщений кодируются с помощью этих ключей. Для клиента это происходит, после того как он верифицировал идентификатор сессии, сформировал новый ключ сессии и послал его серверу. Для сервера это происходит, после того как идентификатор сессии признан корректным, или сервер получил сообщение клиента с ключом сессии. Для сообщений SSLHP (SSL Handshake Protocol) используется следующая нотация:

char MSG-EXAMPLE
char FIELD1
char FIELD2
char THING-MSB
char THING-LSB
char THING-DATA[(MSB<<8)|LSB];
...

Эта нотация определяет данные в протокольном сообщении, включая код типа сообщения. Порядок передачи соответствует порядку перечисления.
Для записи "THING-DATA", значения MSB и LSB в действительности равны THING-MSB и THING-LSB (соответственно) и определяют число байт данных, имеющихся в сообщении. Например, если THING-MSB был равен нулю, а THING-LSB был равен 8, тогда массив THING-DATA будет иметь 8 байт.
Длина кодов характеризуется целым числом без знака, и когда MSB и LSB объединяются, результат также является целым числом без знака. Если не указано обратного, длины полей измеряются в байтах.

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

CLIENT-HELLO (Фаза 1; посылается открыто)
CLIENT-MASTER-KEY (Фаза 1; посылается открыто)
CLIENT-CERTIFICATE (Фаза 2; посылается шифрованным)
CLIENT-FINISHED (Фаза 2; посылается шифрованным)

протокольные сообщения сервера
Существует несколько сообщений, которые генерируются только серверами.
Различают следующие протокольные сообщения сервера:

SERVER-HELLO (Фаза 1; посылается открыто)
SERVER-VERIFY (Фаза 1; посылается шифрованным)
SERVER-FINISHED (Фаза 2; посылается шифрованным)
REQUEST-CERTIFICATE (Фаза 2; посылается шифрованным)

протокольные сообщения клиента/сервера
Эти сообщения генерируются как клиентом, так и сервером.

ERROR (посылается открыто или зашифровано)

char MSG-ERROR
char ERROR-CODE-MSB
char ERROR-CODE-LSB

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

Работа слушателя 4-го курса ИКСИ, научный руководитель — Сергей Кунегин.



Сетевые решения. Статья была опубликована в номере 06 за 2003 год в рубрике технологии

©1999-2024 Сетевые решения