Предположим я скопировал аутентификатор и билет пока они пересекали сеть. Мне придётся изменить сетевой адрес моей рабочей станции и моё пользовательское имя. И всё это я должен проделать за пару минут. Это довольно высокие требования. На самом деле я не думаю, что это возможно. Если только … . . .
Гм. Здесь потенциальная проблема. Предположим что вместо копирования билета и аутентификатора во время их путешествия от твоего рабочего места на сервер, я копирую весь исходный пакет, который пришёл от Харона, то есть тот пакет, который ты получил, когда запрашивал у Харона получение билета.
Этот пакет, как я помню, имеет две копии сессионного ключа: один для тебя и один для сервиса. Тот, который предназначен для сервиса скрыт внутри билета и я не смогу получить его, но как насчёт другого, который кто угодно может использовать для создания аутентификаторов?
Если я смогу получить копию сессионного ключа, я смогу создать мой собственный аутентификатор, и если я могу его создать, я смогу взломать систему.
Афина:
Это то, о чём я думала всю ночь, но когда я проследила весь процесс получения билетов я обнаружила, что невозможно похитить аутентификаторы таким образом.
Ты садишься за своё рабочее место и используешь программу kinit чтобы получить твой TGT. Kinit запрашивает твоё имя и после того, как ты введёшь его kinit отправляет его Харону.
Харон использует твоё имя, чтобы найти твой пароль в своей базе данных, затем продолжает создание TGT для тебя. Как часть этого процесса, он создаёт сессионный ключ, которым ты будешь обменивать с сервисом предоставления билетов (TGS). Затем Харон помещает копию этого ключа в TGT, а твою копию добавляет в пакет, содержащий билет и представляющий ответ Харона. Перед тем, как послать этот пакет, Харон зашифровывает его целиком твоим паролем.
Харон посылает этот пакет через сеть. Кто угодно может его скопировать, в то время пока он перемещается мимо, но никто не сможет ничего с ним сделать потому, что пакет зашифрован твоим паролем. В частности никто не сможет похитить сессионный ключ для TGS.
Kinit Получает этот пакет и запрашивает у тебя пароль, который ты должен ввести. Если ты вводишь правильный пароль, он сможет расшифровать пакет и предоставить тебе ключ сессии.
Теперь, когда ты предоставил kinit возможность закончить свою работу, ты можешь пожелать получить свою почту. Ты запускаешь почтового клиента. Эта программа пытается найти билет для почтового сервиса и не находит его (ведь ты ещё на пытался получить почту). Почтовый клиент должен использовать TGT, чтобы запросить у TGS билет для почтового сервиса.
Клиент создаёт аутентфикатор для обмена с TGS и шифрует его своей копией сессионного ключа для TGS. Затем клиент посылает Харону этот аутентификатор, TGT, твоё имя, адрес твоего компьютера и имя почтового сервиса.
TGS получает всё это и начинает выполнять проверки удостоверения личности отправителя. Если все они удачны, TGS в конце концёв получает ключ сессии, общий для него и тебя и создаёт твой билет почтового сервиса, и новый сессионный ключ, с помощью которого ты будешь обмениваться с почтовым сервисом.
TGS теперь приготавливает пакет с билетом готовый к отправке на твоё рабочее место. Пакет включает билет и твою копию сессионного ключа для почтового сервиса. Но перед тем как послать пакет, он шифрует его копией СВОЕГО сессионного ключа. Дело сделано. Пакет отправляется по своему пути.
Итак теперь мы имеем пакет с билетом почтового сервиса, спешащий по сети. Предположим некое сетевое чудовище копирует его в это время. Ему не повезёт потому, что пакет зашифрован сессионным ключом TGS; а ты и TGS два единственных существа, которые знают этот ключ. Из-за этого окажется невозможным расшифровать пакет с почтовым билетом, и он не сможет получить ПОЧТОВЫЙ КЛЮЧ СЕССИИ. Без этого ключа невозможно использовать любой из почтовых билетов которые ты возможно будешь потом посылать по сети.
Итак я думаю, что мы в безопасности. А что думаешь ты?
Еврепид: Возможно.
Афина: Возможно?! Это всё что ты можешь сказать?!
Еврепид: (смеясь) Не расстраивайся. Тебе следует знать мою точку зрения. Я понимаю, что это нечестно с моей стороны — ты не спала половину ночи.
Афина: фффф!
Еврепид: Ну хорошо, пусть будет три четверти ночи. Действительно система начинает казаться вполне приемлимой. Сессионные ключи решают задачу на которой я сам думал этой же ночью: проблему взаимного удостоверения подлинности.
Пауза.
Могу я поговорить минуту?
Афина: (Несколько настороженно) Пожалуй.
Еврепид:
Ты так добра. (Еврепид откашливаясь) В последнюю ночь пока видения сессионных ключей и аутентификаторов бродили в твоём уме, я пытался найти другие проблемы в системе, я нашёл одну, которая казалась мне очень серьёзной. Я проиллюстрирую её следующим примером.
Предположим, что тебе надоела твоя работа и ты решила, что в твоих интересах будет её поменять. У тебя возникло желание напечатать своё резюме на фирменном супер-принтере так, чтобы сотрудники рекрутских фирм и потенциальные работодатели смогли заметить твой уровень.
Итак ты вводишь команду печати и указываешь в ней задание послать резюме на подходящий принт-сервер. Программа получает правильный билет, если его у тебя ещё не было, и затем посылает билет от твоего имени на этот сервер. Как минимум это, то что ты от неё ожидаешь. Ты на самом деле не знаешь, что запрос направляется обязательно на правильный сервер.
Предположим какой-то не очень разборчивый в средствах хакер – скажем твой босс – перенастроил систему так, что она перенаправляет запросы и билеты на принтер в его кабинете. Этот сервис может даже и не обращать внимание на билет и его содержимое. Он просто отбрасывает билет и посылает сообщение на твою рабочую станцию, что билет выдержал испытание и, что работающий на нём сервис готов печатать твоё задание. Программа печати посылает задание на принтер мошенника и твой враг получает твоё резюме.
Я рассмотрел задачу с противоположной точки зрения. Без сессионных ключей Харон может защитить свои сервисы от фальшивых пользователей, но он не может защитить своих пользователей от фальшивых сервисов. Системе нужен способ для клиентских программ удостовериться в подлинности сервиса перед посылкой ему информации. Система должна позволять взаимную аутентификацию.
Но ключ сессии решает и эту задачу, если твоя клиентская программа написана правильно. Возвращаясь к примеру с сервисом печати: я хочу такую программу печати, которая удостоверятся, что сервис для которого она отправляет задание является законным.
И вот что такая программа делает. Я ввожу её имя с параметрами печати включающими имя файла для печати — моё резюме. Предположим, что я уже имею билет и ключ сессии. Клиентская программа использует сессионный ключ, чтобы создать аутентификатор, затем посылает аутентфикатор и билет “желаемому” серверу печати. Клиент ЕЩЁ НЕ ПОСЫЛАЕТ резюме; он ожидает ответа сервиса.
Реальный сервис получает билет и аутентификатор, расшифровывает билет и извлекает сессионный ключ, а затем использует его, чтобы расшифровать аутентификатор. Когда всё сделано, сервис выполняет все обычные проверки для удостоверения в личности клиента.
Предположим проверка подтвердила мою личность. Теперь сервис подготавливает ответный пакет, так чтобы доказать свою подлинность клиентской программе. Он использует сессионный ключ, чтобы зашифровать ответный пакет, и посылает его ожидающему клиенту.
Клиент получает пакет и пытается расшифровать его своей копией сессионного ключа. Если пакет удалось расшифровать и он содержит правильное сообщение от сервиса, моя клиентская программа знает, что сервис, который зашифровал пакет является настоящим сервисом. Теперь клиент посылает задание печатать резюме.
Предпололжим, что мой босс перенастроил систему, так, что сервис выглядит так как будто он тот который мне нужен. Моя программа посылает аутентификатор и билет “сервису печати” и ожидает ответ. Фальшивый сервис печати не может сгенерировать правильный ответ, потому, что он не смог расшифровать билет и получить сессионный ключ. Моя программа не будет посылать задание если не получить правильного ответа. Очевидно, клиент в конце концёв прервёт ожидание и выйдет. Задание не будет выполнено, но хотя бы резюме не попадёт на стол моего врага.
Ты знаешь, я думаю у нас есть крепкий фундамент на котором мы сможем построить Систему Аутентификации Харон.
Афина: Возможно. Но в любом случае, мне не нравится имя “Харон”.
Еврепид: Да ну! Давно ли?
Афина: Оно мне никогда не нравилось из-за своей бессмысленности. Я разговаривала с моим дядюшкой Гадесом об этом день назад, и он мне предложил другое имя — кличку его трехголового сторожевого пса.
Еврепид: О! Ты имеешь в виду “Цербер”?
Афина: Прикуси свой язык! “Цербер”… как же!
Еврепид: Эээ… Разве его зовут не так?
Афина: Так. Только если бы ты был римлянином! А я греческая богиня, он греческий сторожевой пёс и его имя — Керберос. Керберос с первой буквой “К”.
Еврепид: Хорошо, хорошо не разбрасывай громы и молнии. Я принимаю твоё имя. Действительно оно приятно звучит. Прощай Харон и здравствуй Керберос.
Послесловие
Эта пьеса был написан в 1988 году, чтобы помочь читателям понять основные причины по которым протокол Керберос 4 был реализован именно так. И в течении многих лет это удавалось.
Когда я преобразовывал этот документ в HTML я был поражён насколько он остался актуальным для новой, пятой, версии протокола. Хотя многие вещи изменились, основные идеи протокола остались теми же. В действительность есть только два существенных отличия 5-ой версии от описания протокола в этой пьесе.
Первое изменение было сделано из-за обнаружения того, что небольшое пятиминутное отклонение времени не могло оказаться достаточно надёжным, чтобы предотвратить атаку с помощью повторного использования билета со стороны взломщика, который использует программу автоматического перехвата билета и аутентификатора в то время, как они пересекают сеть, и затем немедленно посылает их вновь.
В пятой версии аутентификаторы сделаны по настоящему одноразовыми с помощью сервисов, получающих билеты, которые имеют “список повторов” в котором он отмечает аутентификаторы, которые недавно поступали на сервер. Если взломщик пытается захватить аутентификатор и использовать его, даже в пятиминутный промежуток, с помощью списка повторов возможно определить, что аутентификатор уже однажды приходил на сервер.
Второе большое отличие протокола то, что билет больше не шифруется пользовательским паролем когда он посылается от сервиса Керберос для kinit во время первоначального обмена билетами. Билет уже и так зашифрован секретным ключом TGS; более того в дальнейшем, когда он используется для получения других билетов, он посылается через сеть в незашифрованном виде. Значит нет причины по которой билет должен быть зашифрован ещё раз Hence, there is no reason why the ticket should be encrypted again пользовательским паролем. (Остаток ответа сервера Керберос пользователю, включая например пользовательскую копию сессионного ключа по прежнему, конечно, зашифрован пользовательским паролем. )
Похожие изменения были сделаны и в протоколе TGS; билеты возвращённые TGS также больше не шифруются ключом сервиса, так как билеты приложений уже зашифрованы их ключами. Так например пакет, который в Керберос V4 мог бы выглядеть так:
ОТВЕТ_KDC = {БИЛЕТ, клиент, сервис, K_сессии}K_пользователя
где “{X}K_Y” означает “X зашифрован ключом K_Y”, а
БИЛЕТ = {клиент, сервис, время_получения, время жизни,
K_сессии}K_сервиса
В пятой версии Керберос ОТВЕТ_KDC выглядит так:
ОТВЕТ_KDC = БИЛЕТ, {клиент, сервиса, K_сессии}K_пользователя
Конечно, в пятой версии появилось ещё много изменений. Пользователи теперь могут безопасно передавать их билеты на другие машины, так что они могут использоваться с другого сетевого адреса; в добавок пользователи могут также делегировать часть своих прав сервису, так, что он может играть роль посредника с поведением аналогичным пользовательскому. Кроме того можно заменить DES другим более надёжным алгоритмом шифрования, таким как triple-DES. Читатели которым интересны остальные отличия между четвёртой и пятой версиями протокола могут прочитать о них в The Evolution of the Kerberos Authentication System, написанной Cliff Neumann и Theodore Ts’o.
Я надеюсь вы получили удовольствие от этого небольшого введения в протокол Керберос. Желаю вам дальнейших открытий!
Теодор Тсо, февраль 1997.
Разрешается использование, копирование, модификация и распространение этого документа для любых целей и без оплаты, при условии что сохранения авторства и указания его в каждой копии, а также присутствия данных об авторстве и этого разрешения в сопровождающих документах. Запрещается использоваться имя M.I.T. в рекламе или других публикациях связанных с распространением без предварительного разрешения. M.I.T. не несёт ответственности за использование этого документа в любых целях. Документ поставляется “как есть” без всяких явных или неявных гарантий.
Для комментариев/предложений пишите: tytso@mit.edu
Leave a Reply