antiCisco blogs


блоги по технологиям и оборудованию cisco от инструкторов

Опубликовано 7 Март , 2010

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

Рассмотрим самую распространенную схему – у каждой из сторон по паре ключей. В каждой паре один ключ называется открытым и его можно передавать по незащищенным каналам связи, а второй – закрытым и его никогда не передают по открытым канал связи.
В схеме RSA (Rivest-Shamir-Adelman) используются 2 ключа (это очень большие простые числа), один из которых называют закрытым и хранят в недоступном для посторонних месте, а другой – открытым и рассылают при необходимости контрагенту.

Пусть у нас есть ключи хоста A: открытый E(A) (encrypt) и D(A) (decrypt)
Обозначим преобразование входного массива данных на ключе K как
[массив]K

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

Тогда для произвольной строки text выполняется равенство:

[[text]E(A)]D(A)=text

И наоборот

[[text]D(A)]E(A)=text

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

Пример:
Пусть хост А хочет передать хосту В некие конфиденциальные данные (text). Тогда он должен каким-либо образом раздобыть открытый ключ хоста В (как это сделать в реальных сетевых условиях рассмотрим позже, а пока предположим, что есть специальная «доска объявлений», на которой «приколоты» все нужные открытые ключи). Дальше нужный текст шифруется

cipherB=[text]E(B)

и полученный шифр передается по сети. Не имея закрытого ключа хоста В «взломать» шифр практически невозможно (вернее, невозможно за разумное время с большой вероятностью. Подробнее о том, почему RSA сложный для взлома можно прочитать в литературе по RSA. Можно также ознакомиться в брошюре …)
На принимающей стороне хост В производит расшифровывание и получает исходный текст:

[cipherB]D(B) = text

В приведенном примере есть одна тонкость: хост В пока никак не может удостовериться, что именно хост А послал ему сообщение, потому что никакой возможности явной проверки нет. Остается только верить 🙂 Чтобы предоставить хосту В возможность проверки источника, необходимо не просто передать текст, а добавить к нему некую проверочную последовательность. Можно делать так:

text+[text]D(A)

Однако, понятно, что при большом объеме данных (text) шифр будет такого же размера и считать его долго. С другой стороны, нам нет необходимости полностью шифровать текст с единственной целью удостоверения отправителя. Нам достаточно зашифровать лишь некую проверочную последовательность. В качестве такой последовательности используется стандартная функция хэширования (sha или md5). Т.е. если стоит задача только удостоверить передающую сторону, делается следующее (ЭЦП):

text+[hash[text]]D(A) = text+ctrlA

На принимающей стороне отделяются последние 128 (md5) или 160 (sha) бит, остаток хэшируется и производится сравнение:

hash[text] V [ctrlA]E(A)

Если в процессе передачи text не изменялся, а также источник именно тот, за кого себя выдает, то легко видеть, что будет равенство (мы по-прежнему подразумеваем наличие общей «доски объявлений» с открытыми ключами)

hash[text]=[ctrlA]E(A)

Ну а если требуется одновременно решать обе эти задачи, т.е. и передавать безопасно конкретному получателю и подтверждать источник, то обе технологии совмещают, т.е. берется text и сторона А делает сообщение:

[text]E(B)+[hash[[text]E(B)]]D(A)= cipherB+[hash[cipherB]]D(A)= cipherB+ctrlA

На принимающей стороне отделяется ctrlA, расшифровывается открытым ключом А. Остаток хешируется и полученные части сравниваются.

Цифровые сертификаты X.509v3

Пока мы оставляли в стороне вопрос «доски объявлений», а именно, насколько можно доверять тому, что на ней опубликовано? Злоумышленник вполне мог вместо легитимного открытого ключа подставить свой и спокойно обманывать всех.

Второй вопрос: а как с сетевой точки зрения сделать такую «доску объявлений?

Обе эти задачи одним махом решаются системой удостоверяющих центров (эдаких сетевых «нотариусов»), которые гарантируют принадлежность открытого ключа.

Каждый удостоверяющий центр (Certification Authority, CA) имеет свою пару ключей E(CA) и D(CA). Эта пара неизменна в течение всей жизни данного CA. СА вырабатывает сам себе сертификат. Формат сертификата зависит от стандарта. Рассмотрим самый распространенный формат: X.509v3
Сертификат — это в-основном хранилище и «переносчик» открытого ключа. «Бумажка», удостоверяющая владельца. В сертификате обязательно содержатся следующие поля:
1. Время жизни сертификата. Это поле проставляет сертификатный сервер в соответствии со своими настройками.
2. Кому выдан (поле subject). В нем содержатся данные владельца сертификата, например, имя, департамент, организация, e-mail и т.д. Эти параметры передаются тем, кто запрашивает сертификат
3. Кем выдан (поле issuer). Данные выдавшего сертификатного сервера. Имя, а также дополнительные параметры. Заполняется сервером сертификатов
4. Открытый ключ владельца. Передается владельцем при запросе на изготовление сертификата.
5. Цифровая подпись. Весь выданный сертификат со всеми полями подписывается электронной цифровой подписью сервера сертификатов, тем самым удостоверяя все данные. Для надежности может даже быть 2 цифровых подписи: с хэшем md5 и sha.

Сервер сертификатов вырабатывает себе так называемый самоподписанный (корневой, root) сертификат. У этого сертификата есть отличительная особенность: поле subject равно полю issuer. Запишем тело сертификата как открытый ключ плюс атрибуты (ATTR). Тогда схематически это можно описать так :

certCA=E(CA)+ATTR(CA)+[hash[E(CA)+ATTRCA]]D(CA)

Как видите, в корневом сертификате используется свой же закрытый ключ. А это значит, что такой сертификат может себе изготовить каждый. Именно поэтому все браузеры ругаются (предупреждают об опасности) при получении от сайта по https самоподписанный сертификат в качестве удостоверяющего, ибо его никак не получится проверить. Останется только переложить ответственность на пользователя, чтобы тот дрожащей рукой ткнул в «все равно продолжить» на свой страх и риск 🙂
Поэтому-то нам важен этап аутентификации самого сервера, чтобы никакой злоумышленник не подменил идентификатор сервера в своих гнусных целях. Аутентификация сервера может производиться разными способами. Например, может каким-либо несетевым способом доставляться корневой сертификат сервера СА на клиентскую машину. Курьером/голубями/на бумажке. Либо проверочная сумма сертификата (как правило, хэш корневого сертификата – fingerprint) лежит на закрытой странице сайта или её можно проверить по телефону.

После того, как мы стали доверять центру сертификатов, т.е. каким-либо образом получили его корневой сертификат и положили в хранилище доверенных корневых сертификатов, наступает этап запроса на выработку нам сертификата данным сервером сертификатов (enrollment).
На этом этапе запрашивающий хост создает стандартный запрос, в который включает свой открытый ключ, атрибуты поля subject (имя, департамент, e-mail и т.д.) отправляет свой запрос. Либо по сети (по протоколу SCEP – Simple Certificate Enrollment Protocol), либо используя GUI сервера, заполняя соответствующие поля запроса или напрямую передавая ему запрос в виде файла. В любом случае все атрибуты попадают на сервер сертификатов, и тот вырабатывает нам наш собственный (идентифицирующий, identity) сертификат:

certA=E(A)+ATTR(A)+[hash[E(A)+ ATTR(A)]]D(CA)

Как видно, наш сертификат уже не самоподписанный, а защищен ЭЦП сервера сертификатов.

Таким образом, на каждом хосте для их взаимодействия, должно быть 2 сертификата: корневой сертификат используемого сервера сертификатов, которому мы доверяем, а также наш собственный, идентифицирующий сертификат, подписанный сервером. Тогда если 2 хоста, А и В хотят пообщаться, происходит обмен сертификатами и следующие 3 проверки:
1. Идентифицирующий сертификат должен быть действителен. Время жизни не должно истечь. А проверяем мы по своим локальным часам, значит часам надо уделить пристальнейшее внимание: сбой сервера ntp или просто нарушение даты может перечеркнуть все наши старания при работе с сертификатами.
2. Сертификат должен быть подписан сервером, которому мы доверяем. И неизменен. Пусть сертификат хоста В выглядит так:

certB = E(B)+ATTR(B)+[hash[E(B)+ ATTR(B)]]D(CA)= E(B)+ATTR(B)+ctrlB

Тогда на хосте А проводим проверку: отделяем поле цифровой подписи (ctrlB), расшифровываем его, используя корневой сертификат, хэшируем остаток и сравниваем

hash[E(B)+ ATTR(B)] V [ctrlB]E(CA)

Если полученный сертификат подписан кем надо и не изменялся после выдачи, то будет равенство:

hash[E(B)+ ATTR(B)] = [ctrlB]E(CA)

3. И ещё можно проводить проверку, не отозван ли присланный сертификат по каким-то причинам. Для этого на сервере сертификатов хранится список отозванных сертификатов (Certificate Revocation List, CRL). Это просто перечисление номеров всех отозванных сертификатов. Посмотреть может каждый. Но этот список подписан ЭЦП сервера сертификатов, поэтому его всегда можно проверить, не изменен ли он злонамеренно.

Здесь уместно отметить, что поиск корневого сертификата для проверки ЭЦП ведется по имени (subject). Поэтому не удивительно, что указав, например, в браузере адрес, а не имя, вы получите предупреждение, что от данного хоста получен сертификат, выданный другому и ему нет доверия. Конечно, сертификат выдан для хоста с именем (CN), а обращаемся мы на ip адрес.

И поле сертификата со ссылкой на список отозванных сертификатов содержит имя сервера. Поэтому часто в корпоративных серверах СА бывает проблема – не доступен CRL. А все потому, что при установке серверу задали имя, которого нет в DNS. Это поле можно посмотреть и прописать в DNS.

Вот собственно и вся инфраструктура. Можно добавить, что кроме основного корневого центра сертификатов могут существовать еще целая цепочка подчинённых (Registration Authority, RA), которых может быть много для распределения нагрузки. Сертификат RA неразрывно связан с сертификатом СА и часто вся цепочка сертификатов пересылаются клиенту. И список отозванных сертификатов тоже для распределения нагрузки, можно положить не только на сам сервер, но и на другие сервера, доступные по http, ldap или scep. Такие сервера будут называться серверами раздачи списка отозванных сертификатов (CRL Distribution Points).

Если же вы хотите организовать сервис, которому все будут доверять (например, сайт, опубликованный по протоколу https), то либо надо всем клиентам раздать корневой сертификат вашего собственного сервера сертификатов, либо использовать заложенные по умолчанию в большинство ОС корневые сертификаты каких-нибудь грандов (в системах Windows их можно посмотреть в закладке «Доверенные центры сертификации» в оснастке работы с сертификатами). Правда, изготовленный для вас сертификат уже не будет бесплатным. 🙂
_______________________________________________
Примечание для читателей блога: к сожалению HTML скушал нижние регистры и формулы стали трудночитаемыми 🙁 Пока публикую так, пока не научился лучше делать. В любом случае более приятный формат есть по ссылке: тут Часть II. Глава 5.

 

Метки: , , ,
Опубликовано: Безопасность cisco

 

» Оставить комментарий

Вы должны войти чтобы прокомментировать.