Содержание статьи
info
Это близкий к тексту пересказ поста The cryptography behind passkeys из блога The Trail of Bits. Автор — Йоп ван де Пол. Этот материал доступен без платной подписки.
Не будем здесь долго разглагольствовать о том, что такое passkeys и почему они круче паролей, — этой темой уже занялись многие ресурсы весьма подробно.
Вместо этого заглянем под капот и разберемся в криптографических механизмах, стоящих за passkeys: какие гарантии они дают или не дают и что интересного можно с этим сделать, например как создавать криптографические ключи и хранить сертификаты.
Также поговорим о главной спецификации passkeys — WebAuthn и покажем, как использовать расширения механизмов ключей доступа для создания более сложных систем с разными возможностями.
Основы
Passkeys — это, по сути, пара криптографических ключей: один публичный (открытый), другой приватный (секретный).
Когда ты создаешь passkey (парольный ключ) на сайте, тот сохраняет у себя только публичный ключ и специальный идентификатор, связанный с этим ключом.
Потом, когда ты пытаешься войти на сайт, он отправляет тебе специальную задачу (вызов), которую нужно подписать приватным ключом. Вместе с ответом ты отправляешь и идентификатор, чтобы сайт знал, какой публичный ключ использовать для проверки. Если подпись правильная — вход разрешается.
С точки зрения криптографии тут все просто. Закрытый ключ подтверждает твою личность, но на сервер не уходит ничего такого, что могло бы пригодиться взломщику. Если серверная задача сгенерирована правильно, например как случайная последовательность из 32 байт, то это защитит от перебора. Сервер хранит только открытый ключ, и, поскольку ты ничего важного туда не отправляешь, в случае взлома никаких утечек не будет.
Но одних только цифровых подписей недостаточно, чтобы решить проблему фишинга. Если остановиться только на криптографии, пользователи все равно остаются под угрозой. Например, без дополнительных мер злоумышленник может уговорить пользователя подписать что‑то от имени другого сайта или использовать одну и ту же пару ключей на нескольких сайтах.
Вот почему passkeys созданы на основе спецификации WebAuthn от W3C, которая добавляет к базовой криптографии важные защитные механизмы. Давай разберемся, как WebAuthn превращает эти простые криптографические фичи в систему аутентификации, стойкую к фишингу.
Веб-аутентификация (WebAuthn)
WebAuthn — это основа технологии passkeys. Если по‑простому, то это работает так: ты заходишь на сайт (он же — relying party) через браузер (в роли WebAuthn user agent), используя любое устройство — ноутбук, смартфон или ПК. Браузер общается с аутентификатором — железкой или программой, которая генерит ключевую пару для passkeys и создает цифровые подписи с ее помощью.

На схеме выше ты можешь увидеть, как работает аутентификация с использованием passkeys:
- Сайт запрашивает авторизацию через браузер.
- Браузер связывается с аутентификатором.
- Аутентификатор проверяет логин, пароль и присутствие пользователя.
- Аутентификатор возвращает подписанный ответ.
- Браузер отправляет этот ответ на сайт для проверки.
Взаимодействие между браузером и устройством аутентификации описано подробнее в другой спецификации — протоколе Client to Authenticator Protocol (CTAP) от FIDO Alliance. Мы сейчас упрощаем для ясности; спецификация WebAuthn предоставляет больше вариантов использования (например, все может происходить в мобильном приложении вместо сайта или браузера). Но эти детали для общего понимания механизма не так важны.
Защита от фишинга
WebAuthn решает проблему фишинга с помощью привязки к источнику. По спецификации браузеры обязаны передавать аутентификатору информацию об источнике запроса, проще говоря — сообщать домен сайта. Аутентификатор, в свою очередь, использует passkeys только в том случае, если сайт, с которого пришел запрос, совпадает с тем, что создал этот самый ключ.
Это значит, что, если ты создашь ключ доступа для bank.com, фишинговый сайт на fake-bank.com просто не сможет его использовать — твой аутентификатор откажется выполнять запрос. Каждому сайту выдается своя уникальная пара ключей, что полностью решает проблему повторного использования паролей.
Спецификация допускает только запросы от источников, которые используют HTTPS. Это значит, что запрос исходит от сервера с действительным сертификатом для нужного источника.
Виды аутентификаторов
В общем случае аутентификатор — это «что‑то, что у тебя есть». Аутентификаторы позволяют проверять, реально ли пользователь присутствует в момент аутентификации. Некоторые из них могут еще проверить пользователя по принципу «что‑то, что ты знаешь», например запросив PIN-код, или попытаться убедиться, что ты тот, кем являешься, при помощи биометрии.
Существует два основных типа аутентификаторов:
-
Аутентификаторы платформы. Они обитают прямо внутри твоего гаджета.
- Примеры: iCloud Keychain, Google Password Manager, Windows Hello, 1Password.
- Плюсы: удобство использования, часто предусматривают облачное резервное копирование.
- Минусы: уязвимы, если сам девайс под угрозой компрометации.
-
Переносные аутентификаторы. Это отдельные специализированные устройства.
- Примеры: YubiKeys, Titan Security Keys, Feitian-брелоки.
- Плюсы: максимальная защита, устойчивость к взлому устройства.
- Минусы: легко потерять или сломать, бэкапа обычно нет.
Если платформа умеет общаться с другими устройствами, например по Bluetooth, ее аутентификаторы можно использовать как переносные. Но если речь идет о суперважных приложениях, лучше вооружиться специальными железками — аппаратными ключами безопасности.
Некоторые аутентификаторы показывают тебе детали запроса, для которого они генерируют цифровую подпись. Если же аутентификатор не может этого сделать, браузер отобразит эти данные за него. Всегда проверяй эту информацию, прежде чем одобрять запрос на аутентификацию.
Хранение ключей
Когда юзер регистрируется на сайте с помощью passkeys, аутентификатор создает ключ и идентификатор (так называемый credential ID). Сайт хранит публичный ключ и идентификатор, связывая их с аккаунтом пользователя. Таким образом, сайт может использовать идентификатор, чтобы сообщить аутентификаторам, какой именно ключ они хотят доставить.
У некоторых аутентификаторов большие хранилища, и они сами содержат все пользовательские ключи. Другие этого сделать не могут, поэтому они шифруют ключ и передают зашифрованный вариант сайту как идентификатор во время регистрации.
Когда сайт хочет провести аутентификацию пользователя, он шлет этот идентификатор в браузер, а тот — в аутентификатор, который, в свою очередь, расшифровывает его и использует парольный ключ.
То есть сайт, может быть, и хранит ключ, но, так как ключ зашифрован, в случае взлома сайта злоумышленником пользователю это никак не навредит.
Доверие к устройствам
Теоретически ты можешь просто сохранить пару криптографических ключей в файл, написать какой‑нибудь софт, который будет использовать эти ключи для криптографических операций, и выдать это за аутентификатор. Как сайтам убедиться, что их пользователи применяют надежные аутентификаторы?
Аутентификаторы могут криптографически доказать некоторые факты о своем происхождении (например, кто их производитель), создавая аттестационное заявление, когда пользователь генерирует ключ доступа. Это заявление подтверждается цепочкой сертификатов, подписанных производителем. Это особенно полезно в корпоративной среде, потому что позволяет убедиться, что все используют специфические аутентификаторы, которые соответствуют определенным требованиям безопасности.
Однако аттестация не обязательна: спецификация WebAuthn не требует от аутентификаторов поддержки этой функции.
Потеря доступа
Что делать, если ты потерял свой аутентификатор или он сломался? Со всеми ключами, которыми он управлял, можно распрощаться. Поскольку это случайно сгенерированные криптографические пары, вернуть их уже не получится.
Большинство платформенных аутентификаторов типа iCloud Keychain, Google Password Manager и 1Password дают возможность залить ключи в облако. Но это, конечно, компромисс: восстановимые ключи имеют большую зону риска, ведь злоумышленники могут попытаться стащить их через механизм восстановления.
Короче говоря, важно, чтобы сайты имели возможность для восстановления доступа, когда ты теряешь свои ключи, но при этом не стоит забывать, что именно к этой лазейке могут подкрасться атакующие.
Другие риски
Использование платформенных аутентификаторов с возможностью резервного копирования, конечно, снижает риск потери ключей доступа, но не устраняет его. Если тебя забанят на платформе, прощайте, ключи. А еще платформа может случайно потереть их. Плюс бывает поддержка шейринга ключей с семьей, где несколько человек могут пользоваться общими ключами, — это тоже создает риски. Сайт обязательно должен предупреждать обо всем этом.
Модель угроз
Passkeys — это, конечно, не универсальное решение для безопасности. Давай разберемся, от чего они действительно защищают.
Модель угроз для passkeys показывает, что они защищают от тех же угроз, что и стандартные пароли, но при этом устраняют риск фишинга и повторного использования паролей. Раздел Conformance в спецификации WebAuthn делает очень сильное заявление о том, что сайты, браузеры и аутентификаторы, соответствующие спецификации, считаются «защищенными» от злонамеренных действий.
Но это немного упрощенная картина. Вот несколько вполне реальных атак, которые все еще могут произойти:
- Атаки через браузер. Некоторые аутентификаторы, например YubiKey 5C, не имеют встроенного дисплея и полностью полагаются на браузер, чтобы показать тебе, на каком сайте ты аутентифицируешься. Если твоим браузером завладеет малварь или вредоносное расширение, он может показывать тебе «google.com», в то время как на самом деле отправляет твоему аутентификатору запрос для подписи от «attacker.com».
- Скомпрометированные аутентификаторы. Устойчивость паролей зависит от того, насколько хорошо аутентификатор защищает приватные ключи. Поддельный ключ, зараженное ПО аутентификатора или малварь, изображающая встроенный аутентификатор ОС, могут тайком вытащить твои приватные ключи. Например, покупая якобы YubiKey у ненадежного продавца, ты можешь нарваться на устройство, рассылающее копии твоих ключей кому‑то еще.
Passkeys — штука классная, но они не спасут, если на твой девайс уже попала малварь или спайварь. Зато они работают как неплохие ограничители атаки — каждый раз, когда злоумышленник захочет что‑то подписать, потребуется отдельное взаимодействие пользователя с аутентификатором. Кроме того, ключи доступа не защищают от злоумышленников, которые могут контролировать домен сайта.
Еще одна тонкость, которую стоит учесть владельцам сайтов, — это коллизии ID учетных записей. Спецификация требует, чтобы они были вероятностно уникальными. Это значит, что они генерируются случайно с очень маленьким, но все‑таки не нулевым шансом на дублирование, как это бывает с UUID.
Почему это важно? Когда пользователь регистрирует ключ доступа, сайт сохраняет ID данных для идентификации этого ключа. Если хакер сможет каким‑то образом зарегистрировать ключ с таким же ID, как у жертвы, то это вызовет путаницу при аутентификации.
Это может показаться маловероятным, но представь себе такие сценарии:
- Злоумышленник, который раздобыл ID учетных данных жертвы (скажем, выудив из сетевого трафика), может попытаться зарегистрировать собственный ключ доступа с этим же ID.
- Вредоносное приложение для аутентификации может намеренно генерировать дублирующие ID учетных данных вместо того, чтобы соблюдать протокол о случайности.
- Баги в реализации могут сократить степень случайности при создании ID учетных данных.
Решение простое: сайты должны всегда отклонять попытки регистрации, если ID нового ключа уже совпадает с тем, что есть в базе данных. Это создает простую защиту по принципу «кто успел, тот и съел» против конфликтов идентификаторов.
Расширения
WebAuthn позволяет сайтам запрашивать дополнительные функции (расширения) при создании ключей или входе в аккаунт. Если браузер и аутентификатор поддерживают нужные расширения — они их применят. Если нет — просто проигнорируют, и все будет работать как обычно.
В спецификации WebAuthn перечислены стандартные расширения, а за дополнительными можно обратиться к специальному реестру IANA. Расширения бывают разные: одни нужны для совместимости со старыми системами, другие добавляют новые криптовозможности. Мы поговорим именно про вторую группу.
Псевдорандомная функция (PRF)
Одна из таких фич — это PRF. Она создана на базе расширения hmac-secret
, как написано в FIDO CTAP v2.1. С помощью расширения PRF твой аутентификатор может рассчитывать HMAC-SHA-256, используя фиксированный, случайно сгенерированный 32-байтовый ключ HMAC. Для этого он берет хеш SHA-256 от заранее определенного префикса WebAuthn и добавляет входные данные с сайта.
Хотя эта фича недостаточно гибкая, чтобы развернуть что‑то вроде HKDF (HMAC-based Key Derivation Function), ее можно использовать, чтобы реализовать HKDF Extract — получение стойкого ключа из нестабильного источника.
Large Blob
Еще одно такое расширение называется Large Blob и позволяет аутентификаторам хранить блоб непрозрачных данных, которые сайт способен читать или записывать во время проверки подлинности. Сайт может использовать это для хранения любых (в том числе чувствительных) данных, таких как сертификаты или криптографические ключи.
Потенциальные проблемы
Достичь истинной сквозной безопасности в браузере крайне сложно, а зачастую невозможно. Ведь веб‑криптография работает на JavaScript, который загружается с сервера, и это значит, что злонамеренный сервер может отправить вредоносный JavaScript, который вытаскивает ключи, отправляет расшифрованные сообщения обратно серверу и так далее.
Еще хуже, злонамеренный сервер может отправлять корректный JavaScript большинству пользователей, а вредоносный — конкретной целевой жертве. Внедрение механизма целостности для кода в интернете (например, хранение хеша всех опубликованных версий у доверенной третьей стороны) и техники прозрачности бинарных файлов (например, публично проверяемый, с видимостью попыток подделки лог) — два многообещающих решения этой проблемы.
Заметь, спецификация говорит, что все расширения опциональны. Значит, нет никакой гарантии, что браузеры и аутентификаторы их поддерживают. Поэтому сайты должны проверять, доступны ли нужные расширения, иначе юзеры столкнутся с проблемами при доступе к сервисам. Надеемся, в будущем все основные браузеры и аутентификаторы добавят эту фичу.
Спецификация активно развивается, и на горизонте куча крутых расширений. Среди возможных фич — новые криптографические примитивы, такие как продвинутые схемы цифровых подписей или доказательства с нулевым разглашением. Заслуживают внимания и монотонные счетчики — механизм, защищающий зашифрованные файлы в облаке или на внешнем хранилище от отката к прошлым состояниям.
Выводы
Сейчас самое время переходить на passkeys. Их криптографическая основа дает хорошие гарантии безопасности, так что это отличный выбор для современных систем аутентификации — естественно, при правильной реализации с использованием WebAuthn.
Конечно, это не панацея, но passkeys снимают кучу серьезных проблем, от которых пароли страдали годами: они не передают на серверы конфиденциальную информацию, их не получится переиспользовать на разных сайтах, да и от фишинга защищают благодаря привязке к домену.
Как пользователь — переходи на ключи доступа и осваивай новый стандарт. Аппаратные ключи безопасности — твое лучшее оружие для защиты особо ценных приложений. Аутентификаторы на устройстве — это удобно, и есть возможность делать бэкапы. Когда входишь с ненадежных устройств, используй ключи доступа с другого устройства, которое имеет свой дисплей, чтобы контролировать запросы на авторизацию.
Если ты разработчик, обеспечь поддержку ключей доступа по максимуму. Не забудь подготовить механизмы восстановления аккаунта, так как при утере passkeys невозможно вернуть. Даже встроенные аутентификаторы с функцией резервного копирования несут определенные риски, о которых нужно знать.
Passkeys могут быть и первым фактором аутентификации, и вторым, и даже несколькими сразу. Но разработчикам стоит учитывать их в рамках общей модели угроз.
Чтобы защититься от злонамеренных серверов, например в приложениях с E2EE, внедряй методы целостности подресурсов и прозрачности исполняемых файлов. WebAuthn не стоит на месте — новые расширения открывают больше криптографических возможностей, но учти: поддержка может отличаться в разных браузерах и аутентификаторах.