Интегрированные сети ISDN

         

Алгоритм работы SSL



Рисунок 6.5.1. Алгоритм работы SSL

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

6.5.2.2.1. При отсутствии идентификатора сессии



Client-hello

C ® S:

challenge, cipher_specs

server-hello

S ® C:

connection-id,server_certificate,cipher_specs

client-master-key

C ® S:

{master_key}server_public_key

client-finish

C ® S:

{connection-id}client_write_key

server-verify

S ®

C:

{challenge}server_write_key

server-finish

S ®

C:

{new_session_id}server_write_key

6.5.2.2.2. Идентификатор сессии найден клиентом и сервером

сlient-hello

C ®

S:

challenge, session_id, cipher_specs

server-hello

S ®

C:

connection-id, session_id_hit

client-finish

C ®

S:

{connection-id}client_write_key

server-verify

S ®

C:

{challenge}server_write_key

server-finish

S ®

C:

{session_id}server_write_key

6.5.2.2.3. Использован идентификатор сессии и аутентификация клиента

сlient-hello

C ®

S:

challenge, session_id, cipher_specs

server-hello

S ®

C:

connection-id, session_id_hit

client-finish

C ®

S:

{connection-id}client_write_key

server-verify

S ®

C:

{challenge}server_write_key

request-certificate

S ®

C:

{auth_type,challenge'}server_write_key

client-certificate

C ®

S:

{cert_type,client_cert, response_data}client_write_key

server-finish

S ®

C:

{session_id}server_write_key

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

6.5.2.3. Ошибки

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

NO-CIPHER-ERROR

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

NO-CERTIFICATE-ERROR

Когда послано сообщение REQUEST-CERTIFICATE, эта ошибка может быть прислана, если клиент не имеет сертификата. Эта ошибка устранима.

BAD-CERTIFICATE-ERROR

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

UNSUPPORTED-CERTIFICATE-TYPE-ERROR

Этот отклик присылается, когда клиент/сервер получает тип сертификата, который он не поддерживает. Эта ошибка устранима (только для аутентификации клиента).



6.5.2.4. Сообщения протокола диалога 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 объединяются, результат также является целым числом без знака. Если не указано обратного, длины полей измеряются в байтах.



6.5.2.5. Протокольные сообщения клиента



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



CLIENT-HELLO (Фаза 1; посылается открыто)



char MSG-CLIENT-HELLO

char CLIENT-VERSION-MSB

char CLIENT-VERSION-LSB

char CIPHER-SPECS-LENGTH-MSB

char CIPHER-SPECS-LENGTH-LSB

char SESSION-ID-LENGTH-MSB

char SESSION-ID-LENGTH-LSB

char CHALLENGE-LENGTH-MSB

char CHALLENGE-LENGTH-LSB

char CIPHER-SPECS-DATA[(MSB<<8)|LSB]

char SESSION-ID-DATA[(MSB<<8)|LSB]

char CHALLENGE-DATA[(MSB<<8)|LSB]

Когда клиент впервые подключается к серверу, он должен послать сообщение CLIENT-HELLO. Сервер ожидает это сообщение от клиента первым. Любое другое сообщение от клиента в данных обстоятельствах рассматривается как ошибка.

Клиент посылает серверу свою версию SSL, спецификацию шифров, некоторые данные вызова (challenge data), и данные идентификатора сессии. Данные идентификатора сессии посылаются клиентом только в том случае, когда в его кэше имеется идентификатор сессии, а значение SESSION-ID-LENGTH не равно нулю. Когда идентификатора сессии нет, то значение SESSION-ID-LENGTH должно быть равно нулю. Данные вызова используются для аутентификации сервера. После того как клиент и сервер согласовали пару ключей сессии, сервер присылает сообщение SERVER-VERIFY с зашифрованной формой CHALLENGE-DATA.

Заметим также, что сервер не пошлет сообщения SERVER-HELLO пока не получит сообщения CLIENT-HELLO. Это делается так, чтобы сервер мог в первом сообщении клиенту определить состояние идентификатора сессии клиента (т.e.


улучшить эффективность протокола и уменьшить объем обменов).

Сервер рассматривает сообщение CLIENT-HELLO и проверяет, поддерживает ли он версию программы клиента и хотя бы одну позицию в спецификации шифров клиента. Сервер может опционно отредактировать спецификацию шифров, удалив записи, которые он решил не поддерживать. Отредактированная версия будет прислана в сообщении SERVER-HELLO, если идентификатор сессии не находится в кэше сервера.

Значение CIPHER-SPECS-LENGTH должно быть больше нуля и кратно 3. Код SESSION-ID-LENGTH должен быть равен нулю или 16. Значение CHALLENGE-LENGTH должно быть больше чем ?

16 и ? 32.

Это сообщение должно быть первым, посланным клиентом серверу. После его посылки клиент ждет сообщения SERVER-HELLO. Любое другое сообщение, присланное сервером (кроме ERROR) не допустимо.



CLIENT-MASTER-KEY (Фаза 1; посылается вначале открыто)



char MSG-CLIENT-MASTER-KEY

char CIPHER-KIND[3]

char CLEAR-KEY-LENGTH-MSB

char CLEAR-KEY-LENGTH-LSB

char ENCRYPTED-KEY-LENGTH-MSB

char ENCRYPTED-KEY-LENGTH-LSB

char KEY-ARG-LENGTH-MSB

char KEY-ARG-LENGTH-LSB

char CLEAR-KEY-DATA[MSB<<8|LSB]

char ENCRYPTED-KEY-DATA[MSB<<8|LSB]

char KEY-ARG-DATA[MSB<<8|LSB]

Клиент посылает это сообщение, когда он определил мастерный ключ для работы с сервером. Заметим, что когда идентификатор сессии согласован, это сообщение не посылается.

Поле CIPHER-KIND указывает, какой шифр выбран из спецификации CIPHER-SPECS сервера.

Данные CLEAR-KEY-DATA содержат открытую часть MASTER-KEY. CLEAR-KEY-DATA комбинируются с SECRET-KEY-DATA, чтобы образовать MASTER-KEY, при этом SECRET-KEY-DATA составляет младшие байты MASTER-KEY. ENCRYPTED-KEY-DATA содержит секретные части MASTER-KEY, зашифрованные с использованием общедоступного ключа сервера. Шифруемые блоки формируются с использованием блоков типа 2 PKCS#1 [5]. Информационная часть блока имеет следующий формат:

char SECRET-KEY-DATA[SECRET-LENGTH]

SECRET-LENGTH равно числу байт каждого из ключей сессии. SECRET-LENGTH плюс CLEAR-KEY-LENGTH равно числу байт в ключе шифра (как это определено CIPHER-KIND).


Если после дешифрования SECRET- LENGTH окажется неравным ожидаемому значению, регистрируется ошибка. Ошибкой считается и ситуация, когда CLEAR-KEY-LENGTH не равно нулю и CIPHER-KIND является не экспортным шифром.

Если алгоритм ключа требует аргумента (например, вектора инициализации DES-CBC), тогда поле KEY-ARG-LENGTH будет ненулевым и KEY-ARG-DATA будет содержать соответствующую информацию. Для алгоритмов SSL_CK_RC2_128_CBC_WITH_MD5, SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_CK_IDEA_128_CBC_WITH_MD5, SSL_CK_DES_64_CBC_WITH_MD5 и SSL_CK_DES_192_EDE3_CBC_WITH_MD5 должны присутствовать данные KEY-ARG с длиной 8 байт.

Вычисление ключей сессии клиента и сервера является функцией CIPHER-CHOICE:

SSL_CK_RC4_128_WITH_MD5

SSL_CK_RC4_128_EXPORT40_WITH_MD5

SSL_CK_RC2_128_CBC_WITH_MD5

SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5

SSL_CK_IDEA_128_CBC_WITH_MD5

KEY-MATERIAL-0 = MD5[ MASTER-KEY, "0", CHALLENGE, CONNECTION-ID ]

KEY-MATERIAL-1 = MD5[ MASTER-KEY, "1", CHALLENGE, CONNECTION-ID ]

CLIENT-READ-KEY = KEY-MATERIAL-0[0-15]

CLIENT-WRITE-KEY = KEY-MATERIAL-1[0-15]

Где KEY-MATERIAL-0[0-15] означает первые 16 байт данных KEY-MATERIAL-0, с KEY-MATERIAL-0[0], образующим старший байт CLIENT-READ-KEY.

Данные передаются хэш-функции MD5, начиная с MASTER-KEY, далее следует "0" или "1", затем вызов (CHALLENGE) и, наконец, CONNECTION-ID.

Заметим, что "0" означает ASCII символ нуль (0x30), а не значение нуль. "1" означает ASCII символ 1 (0x31). MD5 выдает 128 бит выходных данных, которые используются в качестве ключа алгоритма шифрования (старший байт хэша MD5 становится старшим байтом ключевого материала).

SSL_CK_DES_64_CBC_WITH_MD5

KEY-MATERIAL-0 = MD5[ MASTER-KEY, CHALLENGE, CONNECTION-ID ]

CLIENT-READ-KEY = KEY-MATERIAL-0[0-7]

CLIENT-WRITE-KEY = KEY-MATERIAL-0[8-15]

Для DES-CBC, 16-байтовый ключевой материал формируется с помощью MD5. Первые 8 байт дайджеста MD5 используются в качестве CLIENT-READ-KEY, в то время как оставшиеся 8 байт используются в качестве CLIENT-WRITE-KEY.


Вектор инициализации берется из KEY-ARG-DATA.

SSL_CK_DES_192_EDE3_CBC_WITH_MD5

KEY-MATERIAL-0 = MD5[ MASTER-KEY, "0", CHALLENGE, CONNECTION-ID ]

KEY-MATERIAL-1 = MD5[ MASTER-KEY, "1", CHALLENGE, CONNECTION-ID ]

KEY-MATERIAL-2 = MD5[ MASTER-KEY, "2", CHALLENGE, CONNECTION-ID ]

CLIENT-READ-KEY-0 = KEY-MATERIAL-0[0-7]

CLIENT-READ-KEY-1 = KEY-MATERIAL-0[8-15]

CLIENT-READ-KEY-2 = KEY-MATERIAL-1[0-7]

CLIENT-WRITE-KEY-0 = KEY-MATERIAL-1[8-15]

CLIENT-WRITE-KEY-1 = KEY-MATERIAL-2[0-7]

CLIENT-WRITE-KEY-2 = KEY-MATERIAL-2[8-15]

Данные передаются хэш-функции MD5 в указанном порядке, слева направо: первым поступает MASTER-KEY, затем "0", "1" или "2", далее CHALLENGE и, наконец, CONNECTION-ID (идентификатор сессии).

Заметим, что "0" означает ascii символ нуль (0x30), а не код нуль. "1" означает ascii символ 1 (0x31). "2" означает ascii символ 2 (0x32).

Всего генерируется 6 ключей, 3 ключа читающей стороны для шифра DES-EDE3 и 3 - для пишущей стороны для функции DES-EDE3. Вектор инициализации формируется в KEY-ARG-DATA.

Вспомним, что MASTER-KEY передан серверу в сообщении CLIENT-MASTER-KEY. CHALLENGE выдается серверу клиентом в сообщении CLIENT-HELLO. CONNECTION-ID передается клиенту от сервера в сообщении SERVER-HELLO. Это делает получаемые в результате ключи, зависящими от исходной и текущей сессии. Заметим, что мастерный ключ никогда не используется для шифрования данных, и следовательно не может быть легко раскрыт.

Сообщение CLIENT-MASTER-KEY должно быть послано после сообщения CLIENT-HELLO и до сообщения CLIENT-FINISHED. Сообщение CLIENT-MASTER-KEY должно быть послано, если сообщение SERVER-HELLO содержит значение SESSION-ID-HIT равное 0.



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



char MSG-CLIENT-CERTIFICATE

char CERTIFICATE-TYPE

char CERTIFICATE-LENGTH-MSB

char CERTIFICATE-LENGTH-LSB

char RESPONSE-LENGTH-MSB

char RESPONSE-LENGTH-LSB

char CERTIFICATE-DATA[MSB<<8|LSB]



char RESPONSE-DATA[MSB<<8|LSB]

Это сообщение посылается клиентом SSL в ответ на сообщение сервера REQUEST-CERTIFICATE. CERTIFICATE-DATA содержит данные, определенные значением CERTIFICATE-TYPE. Сообщение об ошибке ERROR посылается с кодом NO-CERTIFICATE-ERROR, если данный запрос не может быть обработан корректно (например, получатель сообщения не имеет зарегистрированного сертификата). CERTIFICATE-TYPE является одним из:

SSL_X509_CERTIFICATE

CERTIFICATE-DATA содержит подписанный сертификат X.509 (1988) [3].

RESPONSE-DATA несет в себе аутентификационные данные отклика. Эти данные зависят от значения AUTHENTICATION-TYPE, посланного сервером.

Когда код AUTHENTICATION-TYPE равен SSL_AT_MD5_WITH_RSA_ENCRYPTION, тогда RESPONSE-DATA содержит цифровую подпись следующих компонентов (в указанном порядке):

  • KEY-MATERIAL-0


  • KEY-MATERIAL-1 (только если определено типом шифра)


  • KEY-MATERIAL-2 (только если определено типом шифра)


  • CERTIFICATE-CHALLENGE-DATA (из сообщения REQUEST-CERTIFICATE)


  • Сертификат, подписанный сервером (из сообщения SERVER-HELLO).


  • Цифровая подпись формируется с привлечением MD5, полученный хэш шифруется с использованием общедоступного ключа клиента, формат подписи согласуется со стандартом PKCS#1 [5]. Сервер аутентифицирует клиента путем верификации его цифровой подписи. Допускается добавление нового типа AUTHENTICATION-TYPE или идентификатора алгоритма цифровой подписи.

    Это сообщение должно быть послано клиентом только в ответ на сообщение REQUEST-CERTIFICATE сервера.



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



    char MSG-CLIENT-FINISHED

    char CONNECTION-ID[N-1]

    Клиент посылает это сообщение, после успешной обработки соответствующего сообщения сервера. Заметим, что клиент должен быть готов к приему сообщений от сервера, пока не получит сообщение SERVER-FINISHED. Данные CONNECTION-ID представляют собой исходный идентификатор соединения сервера, посланный в его сообщении SERVER-HELLO и зашифрованный посредством согласованного ключа сессии.



    "N" равно числу байт в посланном сообщении, таким образом "N-1" равно числу байт в сообщении за вычетом одного байта заголовка.

    Для версии протокола 2, клиент должен посылать это сообщение после получения сообщения SERVER-HELLO. Если в сообщении SERVER-HELLO флаг SESSION-ID-HIT не равен нулю, тогда сообщение CLIENT-FINISHED посылается немедленно, в противном случае сообщение CLIENT-FINISHED посылается после сообщения CLIENT-MASTER-KEY.



    6.5.2.6. Протокольные сообщения сервера



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



    SERVER-HELLO (Фаза 1; посылается открыто)



    char MSG-SERVER-HELLO

    char SESSION-ID-HIT

    char CERTIFICATE-TYPE

    char SERVER-VERSION-MSB

    char SERVER-VERSION-LSB

    char CERTIFICATE-LENGTH-MSB

    char CERTIFICATE-LENGTH-LSB

    char CIPHER-SPECS-LENGTH-MSB

    char CIPHER-SPECS-LENGTH-LSB

    char CONNECTION-ID-LENGTH-MSB

    char CONNECTION-ID-LENGTH-LSB

    char CERTIFICATE-DATA[MSB<<8|LSB]

    char CIPHER-SPECS-DATA[MSB<<8|LSB]

    char CONNECTION-ID-DATA[MSB<<8|LSB]

    Сервер посылает это сообщение после получения CLIENT-HELLO. Сервер возвращает флаг SESSION-ID-HIT, указывающий, известен ли серверу полученный идентификатор сессии (т.e. хранится ли он в кэше сервера). Флаг SESSION-ID-HIT будет не равен нулю, если клиент посылает серверу идентификатор сессии (в сообщении CLIENT-HELLO с SESSION-ID-LENGTH != 0), а сервер обнаружит этот идентификатор в своем кэше. Если флаг SESSION-ID-HIT не равен нулю, то поля CERTIFICATE-TYPE, CERTIFICATE-LENGTH и CIPHER-SPECS-LENGTH будут содержать код нуль.

    Значение CERTIFICATE-TYPE, если оно не равно нулю, должно содержать одну из перечисленных выше величин (см. информацию о сообщении CLIENT-CERTIFICATE).

    Когда флаг SESSION-ID-HIT равен нулю, сервер укладывает свой сертификат, спецификацию шифров и идентификатор соединения и посылает их клиенту. Используя эту информацию, клиент может сформировать ключ сессии и послать его серверу в сообщении CLIENT-MASTER-KEY.

    Когда флаг SESSION-ID-HIT не равен нулю, как сервер так и клиент вычисляют новую пару ключей сессии, базируясь на мастерном ключе MASTER-KEY, который они получили при создании идентификатора SESSION-ID.


    SERVER-READ-KEY и SERVER-WRITE- KEY получаются из исходных ключей MASTER-KEY тем же способом, что CLIENT-READ-KEY и CLIENT-WRITE-KEY:

    SERVER-READ-KEY = CLIENT-WRITE-KEY

    SERVER-WRITE-KEY = CLIENT-READ-KEY

    Заметим, что когда ключи получены и установлен флаг SESSION-ID-HIT, а сервер обнаружил идентификатор сессии клиента в своем кэше, тогда данные KEY-ARG-DATA используются с момента, когда определен идентификатор SESSION-ID. Это делается, потому что клиент не посылает новых данных KEY-ARG-DATA (напомним, что данные KEY-ARG-DATA посланы в сообщении CLIENT-MASTER-KEY).

    CONNECTION-ID-DATA представляет собой строку случайных байт, используемых сервером и клиентом в разных местах протокола. Сообщение CLIENT-FINISHED содержит зашифрованную версию CONNECTION-ID-DATA. Длина CONNECTION-ID должна лежать между 16 и 32 байтами, включительно.

    CIPHER-SPECS-DATA определяет тип шифра и длину ключа (в битах), которые поддерживает принимающая сторона. Каждая спецификация SESSION-CIPHER-SPEC имеет длину 3 байта и выглядит как:

    char CIPHER-KIND-0

    char CIPHER-KIND-1

    char CIPHER-KIND-2

    Где CIPHER-KIND равен одному из:

  • SSL_CK_RC4_128_WITH_MD5


  • SSL_CK_RC4_128_EXPORT40_WITH_MD5


  • SSL_CK_RC2_128_CBC_WITH_MD5


  • SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5


  • SSL_CK_IDEA_128_CBC_WITH_MD5


  • SSL_CK_DES_64_CBC_WITH_MD5


  • SSL_CK_DES_192_EDE3_CBC_WITH_MD5


  • Этот список не является исчерпывающим и может быть расширен в будущем. Конфигурации этих средств безопасности стандартизованы (см. табл. 6.5.1).




    Содержание раздела