Yubikey - аутентификация по одноразовым паролям

Мне захотелось поближе познакомиться с Yubikey по многим причинам. Для начинающих это устройство - простое и элегантное решение двух главных проблем в современной информационной безопасности - аутентификации и управлением подлинности. Более того, мне действительно нравится как Yubico, компания-производитель ключа Yubikey, старается интегрировать движение OpenSource в свою бизнес-стратегию. В этой статье я рассмотрю три темы, связанные с этим маленьким устройством. Во-первых, расскажу, какие функции есть у Yubikey и как им пользоваться. Во-вторых, объясню, как он работает. И наконец, покажу, как интегрировать аутентификацию Yubikey в свои веб-приложения.

Оригинал: Yubikey One-Time Password Authentication
Автор: Dirk Merkel
Дата: 1 января 2009
Перевод: Александр Тарасов aka oioki
Дата перевода: 16 сентября 2009

Что же это?

Yubikey - это маленький пластиковый ключ, состоящий по сути из USB-коннектора и кнопки. Он напоминает маленькую USB-флешку, его размеры - 18?45?2 мм, а весит он всего 2 грамма. Его легко можно переносить на связке ключей или в кошельке (см. рисунки 1 и 2). Когда вы вставляете его в USB-порт своего компьютера, он определяется как клавиатура, подразумевая, что Yubikey - платформо-независимое устройство, ведь он поддерживает передачу данных по стандарту USB HID (Human Interface Device, Устройство взаимодействия с человеком). Ключ питается от компьютера и поэтому ему не требуется своя батарейка. Все устройство довольно компактно, его можно носить вместе со своими обычными ключами, надев его на кольцо через маленькое отверстие вверху. Позолоченные контакты достаточно крепкие и рассчитаны на время, большее предполагаемого времени жизни устройства. По сведениям компании Yubico, ключом Yubikey можно будет пользоваться, даже если постирать его в стиральной машинке.


Рисунок 1. Вставленный ключ Yubikey


Рисунок 2. Вот такой Yubikey маленький

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

Как этим воспользоваться?

Когда у меня нет доступа к моей собственной системе, для чтения своих электронных писем я пользуюсь RoundCube. RoundCube - это основанное на AJAX веб-приложение, реализующее почтовый клиент. Чтобы воспользоваться им, нужно просто зайти на него с помощью веб-браузера, как например на Gmail и на множество других популярных почтовиков. К счастью, RoundCube является программным продуктом с открытым исходным кодом, написан на PHP, поэтому добавить в него аутентификацию по Yubikey будет достаточно простой задачей.

При обычной установке RoundCube спросит у вас e-mail адрес и пароль. Однако, если внести несколько изменений в исходный код, окно входа в почту будет иметь новое третье поле - Yubikey OTP (one-time password, одноразовый пароль). Теперь для входа в свой почтовый ящик нужно будет ввести свой e-mail, свой пароль (как обычно), затем перенести курсор на третье поле и нажать кнопку на ключе Yubikey. Спустя пару секунд, Yubikey сгенерирует 44-символьную последовательность, завершающуюся символом новой строки. Символ новой строки приводит к тому, что форма будет отправлена, и вам не придется нажимать кнопку Login лишний раз. Если ваш ключ Yubikey действительно связан с этим почтовым аккаунтом, то вы войдете в свой почтовый ящик. Взгляните на картинку 3, на ней показано модифицированное окно входа в ящик.


Рисунок 3. Модифицированное окно входа в почтовый ящик RoundCube

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

Подробнее

Давайте взглянем на последовательность символов, которую Yubikey генерирует и передает на компьютер. Вот пример такой последовательности:

tlerefhcvijlngibueiiuhkeibbcbecehvjiklltnbbl

На самом деле, эта строка является одноразовым паролем, зашифрованным по алгоритму AES-128 и закодированным в ModHex. Сейчас мы разберемся, как именно Yubikey получает такую строку. Взгляните на рисунок 4.


Рисунок 4. Получение строки Yubikey

Устройство начинает с создания 16-байтовой последовательности (см. рисунок 4), в которой отдельные байты размещены следующим образом:

  • Первые шесть байт содержат уникальный секретный идентификатор ключа, который назначается каждому экземпляру Yubikey при его изготовлении и прошивке. Этот идентификатор известен только тому, кто его назначал, и его нельзя никаким образом достать из Yubikey. Шести байтам соответствует 26*8 = 281,474,976,710,656 уникальных битовых комбинаций. По сути это максимальное количество экземпляров ключей Yubikey, которого должно хватить, прежде чем Yubico выпустит новую модель ключа. Это число превышает количество живущих на планете людей в 42 тысячи раз, поэтому на нас всех хватит с запасом.
  • Следующие два байта в нашей последовательности (байты 7 и 8) используются для хранения счетчика сессии в энергонезависимой памяти. Счетчик начинается с нуля и увеличивается при каждой вставке ключа. Двухбайтовый счетчик сессий может хранить 22*8 = 65,536 сессий. Другими словами, можно включать Yubikey трижды в день в течении почти 60 лет, прежде чем счетчик сессий сбросится. Обратите внимание, что в течение каждой сессии можно создавать несколько одноразовых паролей (см. ниже).
  • Следующие три байта, с 9 по 11, используются в качестве временной метки, хранящейся в энергозависимой памяти в течение каждой сессии. Это означает, что при каждом включении устройства, временная метка обнуляется и постепенно увеличивается. Увеличение метки происходит за счет внутреннего таймера с частотой 8 Гц, поэтому значения кончатся спустя 24 дня. Если вы все же окажетесь в такой редкой ситуации, придется просто вытащить Yubikey и вставить его обратно.
  • Байт номер 12 - это счетчик внутри сессии, который начинается с нуля и увеличивается каждый раз при генерации новой последовательности. После максимального значения (255) следующим будет 0.
  • Байты 13 и 14 в последовательности - это псевдослучайные числа, создаваемые автономным осциллятором. Эти байты добавляют дополнительную энтропию к исходной строке.
  • Последние два байта, 15 и 16, содержат контрольную сумму, вычисляемую по алгоритму CRC-16 по всем байтам строки, исходным значением для самих двух байт контрольной суммы считаются нули. Эта сумма необходима для контроля целостности данных.

Каждый раз при нажатии на кнопку Yubikey генерирует эту самую 16-байтовую последовательность. Однако если вы взглянете выше на пример строки, печатаемой Yubikey, вы увидите, что он состоит из 44 символов. Это потому что мы еще не рассмотрели три важных шага, которые проделывает устройство. Во-первых, 16-байтовая последовательность шифруется с помощью ключа AES-128, уникального для каждого экземпляра Yubikey. Во-вторых, Yubikey дописывает зашифрованную 16-байтовую последовательность 6-байтовым плоским публичным идентификатором. Этот публичный идентификатор полностью отличается от секретного идентификатора (байты 1-6 исходной последовательности). Публичный ключ не меняется с течением времени и может быть привязан к аккаунту. Наконец, полностью 22-байтовая последовательность (6 байт публичный идентификатор + 16 зашифрованных байт) кодируется с помощью малоизвестного алгоритма ModHex.

Компания Yubico выбрала этот алгоритм просто потому, что вывод алгоритма ограничивается набором символом, общим для всевозможных клавиатурных раскладок. Так как Yubikey имитирует клавиатуру, необходимо использовать наиболее совместимые клавиатурные настройки. Недостатком алгоритма ModHex является то, что каждый входной байт кодируется двумя, именно поэтому 22-байтовая последовательность превращается в 44-символьную строку. Однако так как Yubikey сам набирает эту последовательность, неудобств это пользователю не создает.

Подробнее о шифровании

Давайте подробнее разберем этап шифрования. В отличие от асимметричных алгоритмов с использованием публичного ключа, например PGP, алгоритм AES является симметричным. Это означает, что как шифрующей, так и дешифрующей стороне нужно обладать ключом AES-128! Этот обмен ключом AES выполняется в момент изготовления устройства. Подобно уникальному идентификатору устройства, уникальный ключ AES-128 генерируется и сохраняется в устройстве прежде, чем Yubico отправит его на реализацию. Компания поддерживает базу данных, в которой уникальный публичный и секретный идентификаторы соответствуют ключам AES. Таким образом, компания Yubico способна предоставлять веб-сервис аутентификации.

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

Если вы хотите сами руководить своим ключом AES, у вас есть два способа. Во-первых, вы можете запросить ключ у компании Yubico. На момент написания статьи, Yubico по требованию высылала компакт-диск с AES-ключом, однако компания также работала над более удобным способом получения ключа через интернет. Во-вторых, можно воспользоваться комплектом разработчика Yubico и запрограммировать ключ самому. Этот способ хорош тем, что вы можете сами назначать ключи AES-128, а также публичный и секретный идентификаторы. Если вы примете такой подход и создадите свой веб-сервис аутентификации, вы устраните какую-либо зависимость от Yubico в своей процедуре аутентификации, что является несомненным плюсом.

Алгоритм проверки: порядок имеет значение

Неудивительно, что процесс проверки одноразового пароля состоит из шагов, обратных к тем, что необходимы для конструирования этого пароля. Простейшая процедура проверки может выглядеть следующим образом. Во-первых, вы декодируете строку с помощью ModHex. Затем разделяете получившуюся байтовую последовательность на публичный идентификатор и 16-байтовую последовательность. Затем с помощью публичного идентификатора вы получаете ключ AES. После дешифрования с помощью ключа AES вы получаете оригинальную 16-байтовую последовательность в плоском виде. Далее, нужно проверить контрольную сумму по алгоритму CRC-16 (последние два байта). Затем нужно проверить соответствие секретного идентификатора тому, который вы получили из базы данных по публичному идентификатору. С помощью счетчика сессий и счетчика внутри сессии убеждаемся, что текущая строка была сформирована позже, чем в прошлый раз успешной аутентификации. Хотя вы точно не знаете, когда именно были сгенерированы две строки, вы всегда можете узнать, в каком порядке. Если строка проходит все эти проверки, можно послать клиенту сигнал успешной аутентификации. В случае, когда хоть одна проверка не проходит, строка отклоняется.

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

Yubico открывает исходники

Вот что меня привлекает в бизнес-модели компании Yubico, так это всевозможные попытки открыть исходные коды своего программного обеспечения. По заявлениям Yubico они планируют получать выручку с производства и продажи устройств, но намерены открывать все исходные коды. К примеру, исходный код упомянутого выше веб-сервиса аутентификации свободно доступен как эталонная реализация. Более того, Yubico предлагает клиентам библиотеки, необходимые для встраивания аутентификации Yubikey в различные приложения и платформы. На данный момент есть клиентские библиотеки для языков Java, C, C#/.NET, PAM, PHP, Ruby, Perl и Python. Все эти библиотеки и программы оформлены в виде проектов на сайте Google Code. В дополнение к этому существуют библиотеки для дешифрации одноразовых паролей на языках C и Java, а также сервер Open ID и средство персонализации, с помощью которого можно запрограммировать свой собственный Yubikey. Хотя эти программные проекты изначально созданы компанией Yubico, но в них участвует множество и других людей. Более того, появилось множество независимых проектов с открытым исходным кодом, которые используют технологию Yubikey. Форум Yubico является хорошим местом, где можно поговорить о подобных проектах и получить хорошую поддержку.

Служба аутентификации Yubico

Когда вы заказываете ключ Yubikey, вы уже можете воспользоваться веб-сервисом аутентификации, предоставляемым компанием Yubico. Сама Yubico поддерживает базу данных всех API-ключей, а также открытый и секретный идентификатор, которыми ключи программируются перед реализацией. Именно поэтому компания решила сразу предлагать сервис аутентификации по этим атрибутам. Впоследствии разработчики могут пользоваться веб-сервисом аутентификации Yubico для проверки одноразовых паролей, полученных от устройства. На сайте Yubico есть страница, на которой можно заказать API-ключ. Любой может получить этот API-ключ. Единственным требованием является отправка корректного одноразового пароля. Это мера направлена на защиту базы данных от кучи поддельных запросов. API-ключ также идет вместе с идентификационным номером.

API-ключ предназначен для подписи/проверки запросов к/от веб-сервиса аутентификации Yubico, с помощью хэш-алгоритма HMAC-SHA1. Это сделано по той причине, что зачастую поддержка SSL на самом деле не реализована в некоторых окружениях, в которых будет работать клиентская библиотека веб-сервиса. Обратите внимание, что SSL использовать необязательно, ведь строка уже зашифрована! Однако SSL все-таки должен быть использован там, где возможно, в целях усиления безопасности. В клиентской библиотеке для языка PHP, к примеру, все что нужно будет сделать, это добавить s к http в том месте, где указывается URL-адрес сервера аутентификации.

Добавление Yubikey-аутентификации к системе Typo

Теперь у нас есть ясное понимание технологии, давайте же сделаем что-нибудь практическое. Например, добавим аутентификацию по Yubikey к существующему приложению. Для ведения блога я пользуюсь Typo. Приложение Typo разработано на платформе Ruby on Rails, последний снимок его исходного кода можно найти в открытом SVN-репозитории проекта. Нравится вам или нет структура приложения RoR, но в данный момент она работает на нас, потому что облегчает поиск файлов, которые нужно изменить. Взгляните на рисунок 5, там изображена основная схема процедуры проверки пароля, которую мы будем реализовывать.


Рисунок 5. Блок-схема проверки одноразового пароля Yubikey

Начнем. Поместим клиентскую библиотеку для языка Ruby - yubico.rb в каталог lib проекта. После добавления соответствующей команды require в файл config/environments.rb, мы можем быть уверены, что библиотека будет доступна из любой точки приложения.

Для аутентификации с помощью Yubikey необходимы две группы настроек. Во-первых, это настройки уровня сайта, а именно API-ключи и соответствующий ID - они необходимы для отправки запросов аутентификации на веб-сервис. Также есть опция, включающая/выключающая аутентификацию по Yubikey на уровне блога. Typo хранит эти настройки, присваивая им серийный номер и сохраняя в поле blogs.settings. Для нас это означает, что нам не придется самостоятельно вносить изменения в базу данных. Однако, необходимо будет адаптировать пользовательский интерфейс и модель данных, используемую для хранения этих настроек внутри приложения. В листинге 1 показан код, который добавляет эти три настройки в соответствующий HTML-шаблон в админке. Аналогично, в листинге 2 приведен код для добавления этих же настроек в модель данных. Это все, что требуется, чтобы Rails нарисовал нам форму для ввода этих настроек и сохранения их в базе данных каждого блога. На рисунке 6 изображен итоговый результат.

Листинг 1. Typo: HTML-код настроек Yubikey уровня блога

файл: app/views/admin/settings/index.html.erb

...
<!-- Yubikey authentication - start -->
<fieldset id="authentication" class="set" style="margin-top:10px;">
  <legend><%= _("Authentication")%></legend>

  <ul>
    <li>
      <label class="float"><%= _("Require Yubikey OTP")%>:</label>
      <input name="setting[yubikey_required]"
          id="yubikey_required" type="checkbox" value="1"
          <%= 'checked="checked"' if this_blog.yubikey_required%> />

      <input name="setting[yubikey_required]" type="hidden"
          value="0" />
    </li>
    <li>
      <label for="yubikey_api_id"
          class="float"><%= _("Yubico API ID")%>:</label>
      <input name="setting[yubikey_api_id]" id="yubikey_api_id"
          type="text" value="<%=h this_blog.yubikey_api_id %>"
          size="6" />

    </li>
    <li>
      <label for="yubikey_api_key"
          class="float"><%= _("Yubico API Key")%>:</label>
      <input name="setting[yubikey_api_key]"
          id="yubikey_api_key" type="text"
          value="<%=h this_blog.yubikey_api_key %>" size="50" />

    </li>
  </ul>
</fieldset>
<!-- Yubikey authentication - end -->
...

Листинг 2. Typo: Добавление настроек Yubikey уровня блога в модель

файл: app/model/blog.rb

...
  # Authentication
  setting :yubikey_required,       :boolean, false
  setting :yubikey_api_id,         :string, ''
  setting :yubikey_api_key,        :string, ''
...


Рисунок 6. Typo: Интерфейс для изменения настроек Yubikey уровня блога

Далее, есть две настройки, которые относятся к пользователю: это Yubikey ID и Yubikey Required. Первая необходима для связывания аккаунта Typo с уникальным открытым идентификатором Yubikey ID пользователя, а последняя позволяет пользователям включать или отключать аутентификацию по Yubikey лишь для себя. Теперь давайте сделаем так, чтобы пользователь мог изменять обе настройки из админки приложения. Чтобы новые настройки появились в пользовательском интерфейсе, я добавил новую секцию в часть HTML-шаблона, содержащего вывод формы редактирования настроек пользователя (см. листинг 3). Благодаря тому, что RoR поддерживает ActiveRecord, нам больше не нужно будет писать никакого кода, сохраняющего настройки в базе данных; однако, нужно добавить соответствующие поля в пользовательскую таблицу, в которой сохраняются настройки с этого экрана. В платформе Rails это осуществляется добавлением миграции базы данных, что по сути является абстрактным способом описания инкрементального изменения базы данных. В нашем случае мы добавляем в пользовательскую таблицу поля yubikey_id и yubikey_required, для этого создаем миграцию, показанную в листинге 4. Теперь нам нужно запустить утилиту rake из командной строки и указать ей обновить базу данных: rake db:migrate. Приятной особенностью миграций Rails является то, что они независимы от провайдера базы данных. Миграцию, которую мы создали в листинге 4, можно использовать в любых СУБД, поддерживаемых приложением Typo. На момент написания данной статьи это были СУБД MySQL, PostgreSQL и SQLite. Итак, мы можем полюбоваться на новые настройки в админке пользователя (см. рисунок 7).

Листинг 3. Typo: HTML-код настроек Yubikey уровня пользователя

файл: app/views/admin/users/_form.html.erb:

...
<li>
  <label class="float" for="user_notify_on_new_articles"><%=
      _("Send notification messages when new articles are posted")%>?
  </label>

  <%= check_box 'user', 'notify_on_new_articles' %>
</li>
<!-- new options for Yubikey authentication - start -->
<li>
  <label class="float" for="user_yubikey_required"><%=
      _("Yubikey Required")%>?
  </label>
  <%= check_box 'user', 'yubikey_required' %>

</li>
<li>
  <label class="float" for="user_yubikey_id"><%=
      _("Yubikey ID")%>:
  </label>
  <%= text_field 'user', 'yubikey_id' %>
</li>
<!-- new options for Yubikey authentication - end -->

</ul>
</fieldset>
<!--[eoform:user]-->

Листинг 4. Typo: Миграция базы данных с настройками Yubikey

файл: db/migrate/071_add_yubikey_columns_to_user.rb:

class AddYubikeyColumnsToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :yubikey_id, :string, 
               :null => false, :default => ''
    add_column :users, :yubikey_required,
               :boolean, :null => false, :default => false
  end

  def self.down
    remove_column :users, :yubikey_id
    remove_column :users, :yubikey_required
  end
end


Рисунок 7. Typo: Интерфейс для изменения настроек Yubikey уровня пользователя

Все, подготовили предварительные шаги, теперь можем сконцентрироваться на собственно аутентификации. Во-первых, давайте создадим поле ввода Yubikey OTP в окне входа в систему, которое появляется, когда аутентификация по Yubikey включена глобально для всего блога. Я сделал это, изменив часть шаблона, который выводит форму входа в системе, как на листинге 5. Обратите внимание, что нам придется всегда выводить поле Yubikey OTP, ведь если пользователь не укажет свое имя, мы не можем знать, требуется ли Yubikey-аутентификация или нет. На рисунке 8 изображено модифицированное окно входа в систему.

Когда пользователь отправит форму, Rails направит введенные данные методу login классу AccountsController (см. листинг 6). Именно здесь нам надо добавить логику аутентификации по Yubikey. После того, как существующий код проверит обычные логин и пароль, у нас формируется объект User, для которого мы знаем, нужна ли ему Yubikey-аутентификация или нет. Если да, то вызываем статический метод authenticate_yubikey на этом объекте. Смотрите листинг 7, мы проверяем, чтобы ни Yubikey OTP с формы входа в систему, ни открытый Yubikey ID не были пустыми. Более того, по определению первые 12 символов одноразового пароля должны совпадать с открытым идентификатором, соответствующим аккаунту. Если все в порядке, мы создаем объект Yubico, который сам отошлет запрос к веб-сервису и обработает результат. Метод попросту возвращает булево значение. "Истина" означает, что пользователь был аутентифицирован. "Ложь" означает неверный одноразовый пароль, либо попытка войти под неавторизованным пользователем - возможно, кто-то пытается взломать аккаунт.

Листинг 5. Typo: Модфицированная HTML-форма входа в систему

файл: app/views/shared/_loginform.html.erb:

<% form_tag :action=> "login" do %>
<ul>
  <li>

    <label for="user_login"><%= _('Username')%>:</label>

    <input type="text" name="user_login" id="user_login" value=""/>
  </li>
  <li>
    <label for="user_password"><%= _('Password') %>:</label>

    <input type="password" name="user_password" id="user_password" />

  </li>
<!-- Yubikey authentication - start -->
<% if this_blog.yubikey_required %>
  <li>
    <label for="yubikey_otp"><%= _('Yubikey OTP') %>:</label>

    <input type="text" name="yubikey_otp" id="yubikey_otp" />
  </li>
<% end %>
<!-- Yubikey authentication - end -->
  <li class="r"><input type="submit" name="login"
      value= "<%= _('Login') %> &#187;"
      class="primary" id="submit" />

  </li>
</ul>
<p><%= link_to
      "&laquo; " + _('Back to ') + this_blog.blog_name,
      this_blog.base_url %></p>
<% end %>

Листинг 6. Typo: Yubikey-аутентификация, часть 1

файл: app/controllers/accounts_controller.rb:

...
def login
  case request.method
    when :post
    self.current_user =
      User.authenticate(params[:user_login], params[:user_password])

    # check whether Yubikey authentication is required and perform
    # authentication
    if logged_in? &&

           (!this_blog.yubikey_required ||
            !self.current_user.yubikey_required ||
            self.current_user.authenticate_yubikey(
                this_blog,
                self.current_user.yubikey_id,
                params[:yubikey_otp]))
      session[:user_id] = self.current_user.id

      flash[:notice]  = _("Login successful")
      redirect_back_or_default :controller => "admin/dashboard",
                               :action => "index"
    else
      flash.now[:notice]  = _("Login unsuccessful")
      @login = params[:user_login]
    end
  end
end
...

Листинг 7. Typo: Yubikey-аутентификация, часть 2

файл: app/model/user.rb

...
  # Authenticate a user's Yubikey ID.
  #
  # Example:
  #   @user.authenticate_yubikey(this_blog, 'thcrefhcvijl',
  #   'thcrefhcvijldvlfugbhrghkibjigdbunhjlfnbtvfbc')
  #
  def authenticate_yubikey(this_blog,
                           yubikey_id = '', yubikey_otp = '')
    if (yubikey_id.empty? ||
        yubikey_otp.empty? ||
        !yubikey_otp[0, 12].eql?(yubikey_id))
      return false
    else
      begin
        yk = Yubico.new(this_blog.yubikey_api_id,
                        this_blog.yubikey_api_key)
        return yk.verify(yubikey_otp).eql?('OK')
      rescue
        return false
      end
    end
  end
...


Рисунок 8. Typo: Модифицированная форма входа в систему

Вот и все! Мой Typo-блог теперь адаптирован к Yubikey. Отправлю свои наработки в репозиторий Typo, в виде патча.

Возможные реализации

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

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

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

Заключение

На своем веб-сайте компания Yubico поддерживает и пополняет список приложений и служб, которые основаны на Yubikey. Существуют модули для WordPress, интеграция с SSH, форума phpBB и вход в систему Windows (коммерческая бета-версия). Как показано выше в примере с Typo, процесс адаптации программы к Yubikey достаточно прост. Надеюсь, что эта статья вдохновит вас, и вы добавите функции аутентификации по Yubikey к своей любимой программе.

Источники информации

Дирк Меркель (Dirk Merkel) - технический директор компании Vivantech Inc. На досуге ему нравится посылать свои патчи хорошим проектам с открытым исходным кодом. Он также пишет о веб-разработке. Живет Дирк в Сан-Диего со своей любимой женой и двумя замечательными дочерьми. Дирку можно написать на адрес dmerkel@vivantech.com.

ВложениеРазмер
10166f1.mini_.jpg25.78 kb
10166f2.mini_.jpg18.42 kb
10166f3.png18.33 kb
10166f4.png60.33 kb
10166f5.png74.01 kb
10166f6.png32.59 kb
10166f7.png10.44 kb
10166f8.png13.86 kb

Fixes, fixes, fixes

Замечательная статья, однако допущено несколько ошибок (может быть, на момент написания статьи всё было именно так, однако сейчас официальная информация другая). Итак:

  • Про счётчик сессий (байты 7-8): он увеличивается не каждый раз, когда ключ включают, а только в том случае, если его используют во время включения. Иными словами, если его вставить и достать, не нажимая на кнопку - этот счётчик не изменится.
  • Про временную метку (байты 9-11): каждый раз при включении ключа временная метка не сбрасывается в ноль, а инициализируется случайным значением. Если значение достигает 0xFFFFFF, то оно сбрасывается в ноль (и дальше продолжит увеличиваться), другие счётчики не будут изменены, ключ продолжит нормально работать.
  • Про счётчик внутри сессии (байт 12): если значение переполняется (из 0xFF в 0), то счётчик сессий увеличивается на 1.

Информация взята с официального сайта: https://www.yubico.com/wp-content/uploads/2014/10/YubiKey-Manual-v3.3.pdf