U2F (англ. Universal 2nd Factor) — открытый, бездрайверный протокол для двухфакторной аутентификации, основанный на вызов-ответной аутентификации, позволяющий интернет-пользователям использовать U2F устройство как второй фактор для аутентификации на большом количестве онлайн-сервисов.
События, связанные с массовыми взломами аккаунтов [п 1] [п 2] [п 3], подтверждают необходимость защиты данных, находящихся на онлайн-сервисах. Часто учётные записи пользователей защищены слабыми паролями [п 4], пользователями используется одинаковый пароль в разных учетных записях, что способствует массовым взломам.[п 5] Поэтому строгая аутентификация становится все более важным требованием. Большинство решений, обеспечивающих строгую аутентификацию дороже и сложнее в использовании (особенно с мобильными устройствами). В то же время, например, второй фактор в виде OTP уязвим для относительно общих атак, таких как фишинг [п 6], смарт-карты требуют специализированного оборудования и/или установки драйверов перед использованием. В идеале база для безопасной аутентификации должна соответствовать таким требованиям, как: использование строгой аутентификации, соблюдение конфиденциальности пользователя, удобство использования и взаимодействие между различными устройствами, с помощью которых производится аутентификация. Для решения этих вопросов образовался FIDO Alliance, некоммерческая организация, сформированная в июле 2012 года[1].
Спецификации протокола U2F v1.0 были опубликованы FIDO Alliance 9 декабря 2014 года[п 7].
30 июня 2015 года были выпущены две новые версии протокола, поддерживающие Bluetooth и NFC, как транспортные протоколы для U2F [п 8]. Таким образом стала возможна аутентификация посредством протокола U2F с помощью мобильных устройств, используя технологию NFC.
В конце 2015 года началась работа над усовершенствованными спецификациями, называемыми FIDO 2.0[п 9].
7 декабря 2016 года были объявлены обновленные спецификации протокола U2F v1.1[п 10].
FIDO U2F протокол основан на криптосистеме с открытым ключом[2].
Во время регистрации проверяющая сторона (веб-сервис, целевой ресурс) отправляет некоторые данные для подписи устройством (то есть генерирует вызов) браузеру. Браузер добавляет к данным URI, с которого был произведен запрос на подпись и ID канала TLS и отправляет их на U2F устройство. Для успешной регистрации, пользователь должен подтвердить свое согласие, пройдя «тест на присутствие пользователя» (например, нажав кнопку, находящуюся непосредственно на U2F устройстве), после чего U2F устройство внутри себя генерирует регистрационно-зависимую (то есть уникальную для данного устройства, веб-сервиса и пользовательского аккаунта) пару открытый/закрытый ключ и соответствующий этой паре дескриптор ключа (key handle(например, случайное число)), далее возвращает открытый ключ, дескриптор ключа, аттестационный сертификат устройства (сервер (необязательно) проверяет подлинность устройства. Например, банковский сайт, возможно, потребует наличия U2F устройства определенных поставщиков) и подпись вызова браузеру. Браузер отправляет эти данные обратно на целевой ресурс, где происходит верификация подписи вызова, запоминается открытый ключ и дескриптор ключа, ассоциирующиеся с данным пользовательским аккаунтом[2].
Во время аутентификации проверяющая сторона отправляет некоторые данные (то есть генерирует вызов) и дескриптор ключа для подписи браузеру. Браузер добавляет к этому URI, с которого был произведен запрос на подпись и ID канала TLS и отправляет на U2F устройство. Прежде чем подписать, U2F устройство должно «увидеть» пройденный «тест на присутствие пользователя». Используя дескриптор ключа, устройство выбирает соответствующий ему закрытый ключ для подписи, и если устройство не «признает» дескриптор или связанный с закрытым ключом URI, то запрос на подпись отклоняется. Если все прошло успешно, то производится подпись данных клиента. Для предотвращения клонирования устройства, внутри него находится счетчик, который при каждой аутентификации увеличивает свое значение. Его значение так же подписывается и отправляется проверяющей стороне[2].
Веб-приложение с помощью браузера контактирует с U2F устройством посредством JavaScript API[2]. Мобильное приложение так же должно «общаться» с устройством посредством API, при построении которого используется понятие web origin (выше упомянутый URI для веб-приложений). Для возможности работы с различными API было решено использовать фасеты (facets). Фасет — это исполнение приложения, контактирующее с проверяющей стороной[3]. Например, приложение Example может иметь реализацию под Android, IOS или веб-приложение. Все это фасеты приложения Example.
Facet ID — это идентификатор (URI), назначаемый исполнению приложения для конкретной платформы[4]:
AppID — это URL, указывающий на JSON файл, содержащий список разрешенных facet IDs. AppID является частью передаваемых данных при регистрации и аутентификации, поэтому для успешного их прохождения нужно, чтобы facet ID был разрешен в списке, содержащем facet IDs, связанном с этим AppID[2][4].
Например, для приложения Example список разрешенных facet IDs может выглядеть следующим образом:
{
"trustedFacets": [{
"version": { "major": 1, "minor" : 0 },
"ids": [
"https://accounts.example.com",
"https://myaccount.example.com",
"https://security.example.com",
"android:apk-key-hash:FD18FA800DD00C0D9D7724328B6...",
"android:apk-key-hash:Rj6gA3QDA2ddyQyi21JXly6gw9...",
"ios:bundle-id:com.example.SecurityKey.dogfood"
]
}]
}
Для операций подписи используется алгоритм ECDSA над кривой P-256, для операций хеширования — SHA-256[5], которые широко доступны на встраиваемых платформах и достаточно надежны[6][7].
Когда ID канала TLS добавляется к данным клиента во время работы протокола, сервер может обнаружить потенциальную атаку посредника. Концепция ID канала TLS представлена в документе IETF[8] и позволяет серверу обнаружить атаку, если есть два раздельных канала TLS. Эта концепция была внедрена в спецификации протокола U2F, но тем не менее в данном подходе были обнаружены проблемы и предложены пути решения[9].
Согласно спецификациям U2F протокола все нижеперечисленные параметры должны быть реализованы в U2F устройстве, но при этом их реализация отдана на усмотрение производителей:
U2F поддерживается Google Chrome, начиная с 38 версии, Opera — начиная с 40 версии[п 12]. Mozilla добавила поддержку U2F в Firefox, которая может быть включена только путём добавления специального дополнения[п 13]. Для браузера Google Chrome на Android OS была осуществлена поддержка U2F протокола посредством использования приложения Google Authenticator и U2F устройства с поддержкой NFC[п 14].