HOTP

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

HOTP (англ. HMAC-Based One-Time Password Algorithm) — алгоритм защищенной аутентификации с использованием одноразового пароля (One Time Password, OTP). Основан на HMAC (SHA-1). Является алгоритмом односторонней аутентификации, а именно: сервер производит аутентификацию клиента

В качестве параметра, отвечающего за динамику генерации паролей, используется событие, то есть сам факт генерации[1]: каждый раз при создании нового пароля, счетчик событий увеличивает свое значение на единицу, и именно это монотонное возрастающее значение используется как основной параметр алгоритма. Вторым параметром для расчета одноразовых паролей является симметричный ключ, который должен быть уникальным для каждого генератора (клиента) и закрытым от всех, кроме сервера и самого генератора (клиента).

История[править | править вики-текст]

Алгоритм впервые формально описан командой IETF в декабре 2005.[2][3] Он стал первым реально успешным проектом Initiative for Open Authentication (OATH).[4] Алгоритмы генерации одноразовых паролей получили в это время широкую популярность, в связи с резким развитием мобильной индустрии. Требовался надежный алгоритм, простой в плане реализации.

В 2008 году HOTP подарил жизнь более сильному алгоритму Time-based One-time Password Algorithm (TOTP), который во многом наследует черты родителя. В сентябре 2010 на основе TOTP был разработан мощный алгоритм аутентификации OATH Challenge-Response Algorithm (OCRA).[4]

Алгоритм HOTP так же внес инновации в технологию генерации одноразовых паролей. Стойкая по тем временам хеш-функция SHA-1 сочеталась с нетривиальным решением наличия счетчика событий. Эти черты подняли HOTP на один уровень с такими проверенными временем алгоритмами как S/KEY.[4]

Счетчики в HOTP и TOTP[править | править вики-текст]

Основным отличием между двумя алгоритмами является генерация пароля на основе метки времени, которую использует в качестве параметра TOTP алгоритм. При этом используется не точное значение времени, а текущий интервал, границы которого были установлены заранее (например, 30 секунд)[5]

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

Благодаря этому, основа для счетчика в HOTP алгоритме, в отличие от других алгоритмов, использующих таймер, защищена от рассинхронизации передающих устройств или слишком большого расстояния между ними (такого расстояния, что ответ от получателя приходит позже, чем истечет время валидности пароля)[2]. Это позволяет HOTP паролям оставаться действительными в течении неограниченного количества времени, в то время как TOTP пароли перестанут быть действительными спустя конкретный промежуток времени

В итоге, при условии использования той же самой хеш-функции, как и в HOTP, данное отличие в работе алгоритма делает TOTP более безопасным и предпочтительным решением для одноразовых паролей[6]

Описание алгоритма[править | править вики-текст]

Обозначения[править | править вики-текст]

  • — Секретный ключ, уникальный для каждого клиента и известный только ему и серверу. Длина — 160 бит (рекомендованная) или 128 бит (минимальная)[1]
  • — Текущее состояние 8-байтового счетчика по событию
  • — Количество цифр в генерируемом пароле
  • — Количество неудачных попыток авторизации, после которых сервер заблокирует соединение с клиентом
  • — Параметр рассинхронизации. Определяет максимальное расхождение между счетчиком сервера и клиента, при котором одноразовый пароль будет принят

Общее описание[править | править вики-текст]

Алгоритм должен возвращать не меньше 6 цифр для обеспечения достаточной безопасности пароля. В зависимости от уровня требований к защите, можно использовать значения для HOTP, состоящие из большего количества цифр, для получения более стойкого к атакам пароля. Работу алгоритма можно описать следующей формулой[1]:

Процесс работы алгоритма можно разбить на следующие этапы:

  1. Создается строка размером в 20 байт, применяя хеш-функцию , инициализированная параметрам и :
  2. Выбираются определенным образом 4 байта из :
    1. Четыре последних бита последнего байта результата преобразуются в число
    2. Последовательность байтов преобразуется в переменную
    3. возвращает последние 31 бита Причина, из-за которой игнорируется старший бит , заключается в разных вариантах реализации целочисленных вычислений у разных процессоров[1]
  3. Результат работы преобразуется к последовательности из цифр:

Пример вычисления 6-значного значения HOTP[править | править вики-текст]

Данный пример[1] демонстрирует работу алгоритма, генерирующего шестизначный числовой пароль из кода аутентификации размером в 160 бит. Пусть на определенном шаге было вычислено значение строки из

int offset = hmac_result[19] & 0xf;
int bin_code = (hmac_result[offset] & 0x7f) << 24
           | (hmac_result[offset+1] & 0xff) << 16
           | (hmac_result[offset+2] & 0xff) <<  8
           | (hmac_result[offset+3] & 0xff);

Тогда результат будет выглядеть следующим образом:

Индекс байта 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Значение 1f 86 98 69 0e 02 ca 16 61 85 50 ef 7f 19 da 8e 94 5b 55 5a
  1. Последний байт имеет значение 0x5a
  2. Значение сдвига, полученное из младших 4 бит - 0xa, это дает нам число 10
  3. Значение 4 последовательных байтов, начиная с 10-ой позиции - 0x50ef7f19, которое преобразуется в двоичный код DBC1[7] (dynamic binary code)
  4. MSB, полученное из DBC1, равно 0x50. Поэтому DBC2 [8]= DBC1 = 0x50ef7f19
  5. Далее, бинарные значения рассматриваются как положительного числа, записанного в порядке от старшего к младшему, у которого первый байт маскируется значением 0x7f.
  6. Для того, чтобы получить шестизначное число для HOTP, необходимо взять число, полученное на предыдущем шаге по модулю 106

Проверка одноразового пароля[править | править вики-текст]

Проверка значений счетчиков[править | править вики-текст]

При создании нового одноразового пароля генератором (клиентом), значение счетчика клиента увеличивается на единицу. В дальнейшем, значение счетчика подается на вход хеш-функции вместе с ключом . После этого, будет отправлено серверу аутентификации, где оно будет сравнено со значением, вычисленном сервером. Если значения совпадают с учетом расхождения не больше параметра рассинхронизации , то сервер увеличивает на единицу значение своего счетчика. Если данные не совпали, то сервер начинает ресинхронизацию и повторяет ее в случае неудачи, пока не будет достигнут предел неудачных попыток аутентификации . После этого, сервер блокирует учетную запись пользователя[1]

Рассинхронизация между клиентом и сервером[править | править вики-текст]

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

  1. Аутентификация не пройдена. Клиент обновил значение счётчика после создания пароля, а значение на сервере не изменилось
  2. Проблема связи. Клиент инкрементировал значение счётчика после отправки пароля, но пароль не достиг сервера

Это приводит к необходимости использования параметра рассинхронизации , который будет отвечать за размеры окна, в пределах которого значения счетчика клиента и сервера будут считаться синхронизированными

Ресинхронизация счетчика[править | править вики-текст]

Ресинхронизация проводится исключительно сервером. Она заключается в расчете нового значения для своего счетчика событий, чтобы его значение совпадало с полученным от клиента в пределах разницы между значениями не более . Если это условие выполняется, то сервер обновляет значение собственного счетчика[1]

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

  1. Ограничения шанса подбора верного значения пароля
  2. Предотвратить зацикливания расчета значения в рамках одной проверки

Безопасность[править | править вики-текст]

Надежность алгоритма[править | править вики-текст]

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

  • Атака вида "человек посередине" (Man-in-the-middle). Злоумышленник не может подделать пересылаемое сообщение, так как пароль изменяется достаточно часто. Множество методов криптографического анализа становятся при этом малопригодны. В некоторых реализациях счетчик, используемый для создания пароля, меняет значение после каждой пересылки. Если сообщения зашифрованы с использованием достаточно сильного шифра, то HOTP делает подбор пароля почти невозможным.[3]
  • Атака повторного воспроизведения. Здесь успех зависит от конфигурации самой системы. В случае, например, когда используется сервер аутентификации для предоставления прав на вход пользователя, у атакующего возникает ряд проблем. Сервер после каждого приема сообщения увеличивает значение счетчика на единицу. Поэтому элементарная отправка дубликата сообщения не пройдет проверку - сообщение создавалось с помощью одного значения, а проверка производится другим.[3]
  • Если ключ состоит из произвольных цифр, то вероятность успеха атаки методом прямого перебора при наличии попыток аутентификации до момента блокировки рассчитывается по формуле . Например, при 5 разрешенных попытках ввода шестизначного пароля и размере допустимого окна шанс успеха при атаке составляет 0.015%

Часто злоумышленнику удается украсть с сервера аутентификации хешированный пользовательский пароль, по которому происходит проверка подлинности. Однако алгоритм для создания пароля использует также счетчик событий. Поскольку начальное значение счетчика выбирается сервером, оно обычно случайное, что затрудняет взлом канала связи даже при наличии у атакующего разделяемого секрета.[3]

Способы повышения защиты[править | править вики-текст]

Данные изменения не являются обязательными или рекомендованными авторами алгоритма расширениями. Однако для повышения уровня безопасности собственной реализации можно применить следующие варианты[1]:

  • Увеличение длины значения HOTP.

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

  • Алфавитно-цифровые значения.

Смысл этой идеи заключается в том, чтобы использовать не только цифры для пароля, но еще и символы A-Z. Вернее, речь идет о наборе из 32 символов из алфавитно-цифрового множества. Сразу же становится видно, как вырос уровень безопасности паролей, потому что теперь вероятность успеха полного перебора составляет для паролей, состоящих из 6 символов.

  • Ресинхронизация на базе счетчика.

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

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

Применение[править | править вики-текст]

Объединение OATH, стандартизовав HOTP, не давало никаких указаний по поводу реализации алгоритма. Напротив, свобода разработчиков позволяет находить все новые решения, стремясь удовлетворить потребности заказчика и внести инновационный вклад в технологию OTP.[2][3][9]

Распространенную реализацию HOTP на Java можно найти в пакете org.jboss.security.otp, который входит в стандартные библиотеки свободно распространяемого веб-сервера Apache Jboss.

Еще одна реализация на языке Java представлена непосредственно объединением OATH в пакете org.openauthentication.otp.

Можно также упомянуть реализацию - проект OATH Toolkit, библиотека liboath которого позволяет создавать пароли в режиме HOTP и TOTP.[10]

Большое количество слабо интеллектуальных устройств специально, созданных для генерации паролей или передачи данных с помощью HOTP и TOTP (Feitian, SecuTech, SmartDisplayer, Vasco, Yubico, Protectimus[11]). Алгоритм также используется в домашних сетях для управления периферией с помощью пульта дистанционного управления или мобильного телефона.[3]

Требования к реализации алгоритма[править | править вики-текст]

  1. Необходимо поддерживать двухфакторную аутентификацию. В данном случае подразумевается, что первым фактором является генератор одноразовых паролей, а вторым - некий дополнительный секрет, который добавляется к одноразовому паролю[3]
  2. Сервер должен быть защищен от атак методом прямого перебора, т. е. учетная запись пользователя должна блокироваться после определенного числа неуспешных попыток аутентификации[1]
  3. Необходимо использовать защищенный канал

В дополнение[править | править вики-текст]

HOTP основан на SHA-1, которая более не считается достаточно устойчивой к коллизиям. Однако, алгоритм HOTP использует только факт случайности числа, посчитанного на её основе, поэтому наличие коллизий непосредственно не влияет на его работу.[2][9]

Односторонняя аутентификация подразумевает, что клиент по потребности пытается установить связь. После чего сервер отправляет запрос обратно клиенту и проверяет его ответ на подлинность. Модификация алгоритма OCRA позволяет так же и пользователю провести аутентификацию сервера.[4]

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

  1. 1 2 3 4 5 6 7 8 9 Hoornaert, Frank, Naccache, David, Bellare, Mihir, Ranen, Ohad. HOTP: An HMAC-Based One-Time Password Algorithm (англ.). tools.ietf.org. Проверено 26 марта 2017.
  2. 1 2 3 4 «Algorithm agility and OATH» by Burt Kaliski, RSA Laboratories.May 19, 2005.
  3. 1 2 3 4 5 6 7 «HOTP-Based User Authentication Scheme in Home Networks» by Binod Vaidya, Jong Hyuk Park and Joel J.P.C. Rodrigues. 2009
  4. 1 2 3 4 «OATH: yesterday, today, and tomorrow» by Nathan Willis, December 15, 2010.
  5. Nathan Schmidt. Nathan Schmidt — Breakdown: HMAC-Based One-Time Passwords (англ.). nathschmidt.net. Проверено 27 марта 2017.
  6. One-Time Passwords – HOTP and TOTP (en-GB), aldaris' blog (28 февраля 2014). Проверено 22 марта 2017.
  7. M. Bellare, R. Canetti and H. Krawczyk Keyed Hash Functions and Message Authentication // Proceedings of Crypto'96, LNCS Vol. 1109, pp. 1-15..
  8. Krawczyk, H., Bellare, M., and R. Canetti HMAC: Keyed-Hashing for Message Authentication // RFC 2104. — 1997. — Февраль.
  9. 1 2 «Attacks on SHA-1» by Initiative for Open AuTHentication,March 2, 2005.
  10. «Introducing the OATH Toolkit» by Simon Josefsson, 2011.
  11. Protectimus.

Ссылки[править | править вики-текст]