Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #72, НОЯБРЬ 2006 г.

без лишних глаз

3APA3A (WWW.SECURITY.NNOV.RU)

Спецвыпуск: Хакер, номер #072, стр. 072-092-3


>>APOP myusername 1cf86d5764a89dfc40a1f32cc20613ac

Сервер вычисляет аналогичную строку и сравнивает результаты. Чем плох такой способ аутентификации, кроме того, что он не совпадает ни с одним другим стандартом? Тем, что сервер обязан хранить пароль в открытом тексте. В случае компрометации сервера пароль может быть похищен. Некоторые почтовые агенты, например, Mozilla Thunderbird, автоматически пытаются переключиться на аутентификацию APOP, если в баннере сервера присутствуют угловые скобки.

[CRAM-MD5.]

В 1997 году появился стандарт RFC 2195, определяющий механизм аутентификации challenge-response для IMAP и POP3 (так называемый CRAM). Стандарт может использоваться с любой криптографической хэш-функцией, например, CRAM-MD5, CRAM-MD4, CRAM-SHA1 и т.д. Стандарт опирается на стандарт того же года RFC 2104, HMAC (Keyed-Hashing for Message Authentication). HMAC как раз и определяет, как использовать ключ (в случае CRAM роль ключа выполняет пароль) совместно с хэш-функцией и сообщением (в случае CRAM роль сообщения выполняет digest). HMAC определяет два производных ключа – внутренний и внешний (ikey и okey). Для применения ключ (то есть пароль) расширяется до размера блока (64 байта для большинства известных алгоритмов) нулями. Для получения ikey каждый байт полученного ключа «ксорится» со значением 0x36 (ipad), okey — 0x5c (opad). Затем HMAC вычисляется как H(okey,H(ikey,text)), где H – хэш-функция (например, MD5). Запятой в данном случае обозначается операция конкатенации.

В чем преимущество данного подхода? Он позволяет серверу не хранить пароль в открытом тексте. Это достигается за счет того, что в каждом из двух вызовов хэш-функции ключ находится в начале хэшируемых данных. Это позволяет «заранее» провести часть вычислений. Например, для MD5 алгоритм будет выглядеть следующим образом:

MD5Init(&context);

MD5Update(&context, ikey, 64);

MD5Update(&context,text,text_len);

MD5Final(digest, &context);

MD5Init(&context);

MD5Update(&context, okey, 64);

MD5Update(&context, digest, 16);

MD5Final(digest, &context);

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

MD5Init(&icontext);

MD5Update(&icontext, ikey, 64);

MD5Init(&ocontext);

MD5Update(&ocontext, okey, 64);

Получили два контекста (icontext и ocontext), которые можем теперь сохранить вместо самого ключа, чтобы использовать в дальнейшем. Если быть точнее, то сохранить придется только состояние контекста (context-> state), так как размер ikey/okey подогнан под размер блока алгоритма. Чтобы получить по этим контекстам и тексту необходимый HMAC:

MD5Update(&icontext,text,text_len);

MD5Final(digest,&icontext);

MD5Update(&ocontext,digest,16);

MD5Final(digest,&ocontext);

Назад на стр. 072-092-2  Содержание  Вперед на стр. 072-092-4