Простой протокол аутентификации с секретным ключом вступает в действие, когда кто-либо стучится в сетевую дверь и просит впустить его. Чтобы доказать свое право на вход, пользователь предъявляет аутентификатор (authenticator) в виде блока информации, зашифрованного с помощью секретного ключа. Содержание этого блока должно меняться при каждом последующем сеансе, в противном случае злоумышленник вполне может проникнуть в систему, воспользовавшись перехваченным сообщением. Получив аутентификатор, привратник расшифровывает его и проверяет полученную информацию, чтобы убедиться в успешности расшифрования. Если все прошло нормально, страж может быть уверен, что человеку, предъявившему аутентификатор, известен секретный ключ. А ведь этот ключ знают всего двое, причем один из них - сам привратник. Таким образом, он делает вывод, что пришелец действительно тот человек, за которого себя выдает.
Но может случиться и так, что субъект, постучавшийся в дверь, захочет провести взаимную аутентификацию. В этом случае используется тот же самый протокол, но в обратном порядке и с некоторыми изменениями. Теперь привратник извлекает из исходного аутентификатора часть информации, а затем шифрует ее, превращая в новый аутентификатор, и в таком виде возвращает пришельцу. Тот, в свою очередь, расшифровывает полученную информацию и сравнивает ее с исходной. Если все совпадает, пришелец может быть уверен: раз привратник расшифровал оригинал, значит, он знает секретный ключ.
А теперь вернемся к нашему примеру. Предположим, Алиса и Боб договорились: перед тем, как пересылать информацию между своими компьютерами, они с помощью известного только им двоим секретного ключа, будут проверять, кто находится на другом конце линии. В ситуации, когда Алиса играет роль осторожного гостя, а Боб - бдительного привратника, это будет выглядеть так.
1. Алиса посылает Бобу сообщение, содержащее ее имя в открытом виде и аутентификатор, зашифрованный с помощью секретного ключа, известного только им двоим. В протоколе аутентификации такое сообщение представляет собой структуру данных с двумя полями. Первое поле содержит информацию об Алисе - ее имя. Во втором поле указывается текущее время на рабочей станции Алисы.
2. Боб получает сообщение и видит, что оно пришло от кого-то, кто называет себя Алисой. Он сразу же достает ключ, которым они с Алисой договорились шифровать аутентификатор, и, расшифровав второе поле, узнает время отправки сообщения.
Задача Боба намного упрощается, если его компьютер работает синхронно с компьютером Алисы, поэтому давайте предположим, что оба они сверяют свои часы с сетевым временем, благодаря чему те идут практически одинаково. Допустим, часы на компьютерах Алисы и Боба никогда не расходятся больше, чем на пять минут. В этом случае Боб может сравнить извлеченное из второго поля аутентификатора значение с текущим временем на своих часах. Если различие составит более пяти минут, компьютер автоматически откажется признавать подлинность аутентификатора.
Если же время оказывается в пределах допустимого отклонения, можно с большой долей уверенности предположить, что аутентификатор поступил именно от Алисы. Но Бобу этого мало, ему нужна полная уверенность. Ведь, рассуждает он, может быть и так: кто-то перехватил предыдущую попытку Алисы связаться со мной и теперь пытается воспользоваться ее аутентификатором. Впрочем, если на компьютере сохранились записи о времени аутентификаторов, поступивших от Алисы за последние пять минут, Боб может найти последний и отказаться от всех других сообщений, отправленных одновременно с ним или ранее. Но если второе поле свидетельствует, что сообщение ушло в сеть уже после отправки последнего аутентификатора Алисы, то и его автором вполне могла быть Алиса.
3. Боб шифрует время из сообщения Алисы с помощью их общего ключа и включает его в собственное сообщение, которое направляет Алисе.
Обратите внимание, что Боб возвращает Алисе не всю информацию из ее аутентификатора, а только время. Если бы он отправил все сразу, у Алисы закралось бы подозрение, что кто-то, решив притвориться Бобом, просто скопировал аутентификатор из ее исходного сообщения и без каких-либо изменений отправил его назад. Но в полученном письме содержится только часть информации, а это значит, что получатель исходного аутентификатора смог расшифровать его и обработать содержащуюся там информацию. А время он выбрал потому, что это поле является уникальным идентификатором сообщения Алисы. Алиса получает ответ Боба, расшифровывает его, а затем сравнивает полученный результат со временем, которое было указано в исходном аутентификаторе. Если эти данные совпадают, она может быть уверена, что ее аутентификатор дошел до того, кто знает их с Бобом секретный ключ. Этот человек смог расшифровать сообщение и извлечь из него информацию о времени. Поскольку ни она, ни Боб никому свой ключ не передавали, Алиса делает вывод, что именно Боб получил ее аутентификатор и ответил на него. Взаимная аутентификация представлена на рисунке 1.
Рисунок 1 - Взаимная аутентификация (Алиса-Боб)
При использовании простых протоколов, наподобие описанного выше, возникает одна очень важная проблема. В случае с Алисой и Бобом мы ни слова не сказали о том, как и где они договаривались о секретном ключе для своей переписки. Конечно, люди могут просто встретиться в парке и обсудить все детали, но ведь в сетевых переговорах участвуют машины. Если под Алисой понимать клиентскую программу, установленную на рабочей станции, а под Бобом - службу на сетевом сервере, то встретиться они никак не могут. Проблема еще более осложняется в тех случаях, когда Алисе - клиенту - нужно посылать сообщения на несколько серверов, ведь для каждого из них придется обзавестись отдельным ключом. Да и службе по имени Боб потребуется столько секретных ключей, сколько у нее клиентов. Но если каждому клиенту для поддержания связи с каждой службой требуется индивидуальный ключ, и такой же ключ нужен каждой службе для каждого клиента, то проблема обмена ключами очень быстро приобретает предельную остроту. Необходимость хранения и защиты такого множества ключей на огромном количестве компьютеров создает невероятный риск для всей системы безопасности.
Само название протокола Kerberos говорит о том, как здесь решена проблема управления ключами. Кербер (или Цербер) - персонаж классической греческой мифологии. Этот свирепый пес о трех головах, по поверьям греков, охраняет врата подземного царства мертвых. Трем головам Кербера в протоколе Kerberos соответствуют три участника безопасной связи: клиент, сервер и доверенный посредник между ними. Роль посредника здесь играет так называемый центр распределения ключей Key Distribution Center или, сокращенно, KDC
KDC представляет собой службу, работающую на физически защищенном сервере. Она ведет базу данных с информацией об учетных записях всех главных абонентов безопасности (security principal) своей области (области Kerberos в сетях Windows 2000 соответствует домен, поэтому в дальнейшем мы будем применять именно этот привычный термин). Вместе с информацией о каждом абоненте безопасности в базе данных KDC сохраняется криптографический ключ, известный только этому абоненту и службе KDC. Данный ключ, который называют долговременным, используется для связи пользователя системы безопасности с центром распределения ключей. В большинстве практических реализаций протокола Kerberos долговременные ключи создаются на основе пароля пользователя.
Когда клиенту нужно обратиться к серверу, он, прежде всего, направляет запрос в центр KDC, который в ответ направляет каждому участнику предстоящего сеанса копии уникального сеансового ключа (sessionkey), действующие в течение короткого времени. Назначение этих ключей - проведение аутентификации клиента и сервера. Копия сеансового ключа, пересылаемая на сервер, шифруется с помощью долговременного ключа этого сервера, а направляемая клиенту - долговременного ключа данного клиента.
Рисунок.2. Управление ключами (в теории)
Теоретически, для выполнения функций доверенного посредника центру KDC достаточно направить сеансовые ключи непосредственно абонентам безопасности, как показано выше. Однако на практике реализовать такую схему чрезвычайно сложно. Прежде всего, серверу пришлось бы сохранять свою копию сеансового ключа в памяти до тех пор, пока клиент не свяжется с ним. А ведь сервер обслуживает не одного клиента, поэтому ему нужно хранить пароли всех клиентов, которые могут потребовать его внимания. В таких условиях управление ключами требует значительной затраты серверных ресурсов, что ограничивает масштабируемость системы. Нельзя забывать и о превратностях сетевого трафика. Они могут привести к тому, что запрос от клиента, уже получившего сеансовый пароль, поступит на сервер раньше, чем сообщение KDC с этим паролем. В результате серверу придется повременить с ответом до тех пор, пока он не получит свою копию сеансового пароля. То есть, нужно будет сохранить состояния сервера, а это накладывает на его ресурсы еще одно тяжкое бремя. Поэтому на практике применяется другая схема управления паролями, которая делает протокол Kerberosгораздо более эффективным. Ее описание приводится ниже.
В ответ на запрос клиента, который намерен подключиться к серверу, служба KDC направляет обе копии сеансового ключа клиенту, как показано на рис.3. Сообщение, предназначенное клиенту, шифруется посредством долговременного ключа клиента, а сеансовый ключ для сервера вместе с информацией о клиенте вкладывается в блок данных, получивший название сеансового билета (session ticket). Затем сеансовый билет целиком шифруется с помощью долговременного ключа сервера, который знают только служба KDC и данный сервер. После этого вся ответственность за обработку билета, несущего в себе зашифрованный сеансовый ключ, возлагается на клиента, который должен доставить его на сервер.