
Портативные, аппаратно-поддерживаемые учетные данные WebAuthn с использованием TPM 2.0. Детерминированный родительский ключ, полученный из мастер-семени, обеспечивает переносимость учетных данных между устройствами. Приватные ключи подписи никогда не покидают TPM. Включает расширение браузера и CLI.
⚠️ Ранняя концептуальная реализация. Этот проект не был тщательно протестирован или проверен. Не используйте его для чего-либо, кроме экспериментов.
Портативные, аппаратно-подкреплённые учётные данные WebAuthn/passkey, работающие на нескольких устройствах с использованием TPM 2.0.
Обычные учётные данные TPM привязаны к устройству, на котором они созданы. Этот проект делает их портативными путём импорта детерминированного родительского ключа (созданного из мастер-сида) в TPM каждого устройства. Зашифрованные блобы учётных данных, созданные одним TPM, могут быть загружены и использованы любым другим TPM, подготовленным с тем же сидом. Закрытые ключи подписи генерируются случайным образом внутри TPM для каждого набора учётных данных и никогда не существуют в открытом виде за пределами аппаратного обеспечения.
Мастер-сид требуется только один раз на устройство во время подготовки. После этого все криптографические операции выполняются полностью внутри TPM.
Расширение браузера переопределяет navigator.credentials и направляет вызовы WebAuthn через нативный обмен сообщениями к бэкенду на Python, который напрямую взаимодействует с TPM. При регистрации TPM создаёт новый ключ подписи под портативным родительским ключом и возвращает зашифрованный блоб. При аутентификации он загружает блоб обратно, расшифровывает его внутренне и подписывает вызов.
Linux (Debian/Ubuntu):
sudo apt install tpm2-tools python3-tpm2-pytss python3-cryptography
Windows:
pip install cryptography
Windows взаимодействует с TPM через TBS (TPM Base Services) через ctypes, поэтому дополнительные нативные пакеты не требуются.
Расширение браузера взаимодействует с native_host.py через нативный обмен сообщениями. Вам нужно зарегистрировать манифест, который сообщит Firefox, где найти хост.
Создайте файл ~/.mozilla/native-messaging-hosts/webauthn_tpm_portable.json:
{
"name": "webauthn_tpm_portable",
"description": "WebAuthn TPM Portable Credentials Backend",
"path": "/absolute/path/to/native_host.py",
"type": "stdio",
"allowed_extensions": [
"[email protected]"
]
}
Замените path на абсолютный путь к native_host.py. Убедитесь, что файл исполняемый (chmod +x native_host.py).
На Windows манифест нативного обмена сообщениями регистрируется через реестр Windows. Подробности см. в документации Firefox по нативному обмену сообщениями.
cd extension
npm install
npm run build
Затем в Firefox:
about:debugging#/runtime/this-firefoxextension/dist (например, manifest.json)Откройте всплывающее окно расширения и либо вставьте существующий сид, либо нажмите "Generate" для создания нового, затем нажмите "Provision". Если вы создаёте новый сид, сохраните его в безопасном месте. Он понадобится для подготовки дополнительных устройств, а его потеря означает потерю возможности настройки новых устройств (существующие учётные данные на уже подготовленных устройствах продолжат работать).
Подготовку также можно выполнить из командной строки:
./webauthn_cli.py provision --generate
# или с существующим сидом:
./webauthn_cli.py provision <seed_hex>
./webauthn_cli.py test
Это создаёт учётные данные, подписывает вызов и проверяет подпись.
webauthn_cli.py [--backend=BACKEND] <command> [args]
Команды:
Бэкенды (выбираются с помощью --backend или переменной окружения WEBAUTHN_BACKEND):
| Бэкенд | Описание |
|---|---|
tpm | Кроссплатформенный TPM через сырые команды (по умолчанию) |
linux | Только Linux, использует библиотеку tpm2-pytss |
soft | Чисто программный, TPM не требуется (для тестирования) |
Ключи подписи учётных данных генерируются внутри TPM и никогда не покидают его в открытом виде. Зашифрованный блоб в идентификаторе учётных данных бесполезен без доступа к подготовленному TPM. В отличие от программных хранилищ учётных данных, закрытые ключи никогда не присутствуют в памяти хоста во время аутентификации, что защищает от атак cold boot и извлечения ключей вредоносным ПО.
TPM2_Duplicate (который теоретически может экспортировать ключи) заблокирован, поскольку учётные данные создаются с пустым authPolicy, что делает дублирование невозможным даже при полном доступе к системе.
Вредоносное ПО, работающее на подготовленной системе, может попросить TPM подписать вызовы, так как отсутствует проверка пользователя (нет нажатия кнопки или биометрии). Оно не может извлечь ключи, но может использовать их, пока активно. Это более узкая поверхность атаки, чем программные хранилища учётных данных, где вредоносное ПО может украсть ключи напрямую.
Мастер-сид является корнем доверия. Если он скомпрометирован, злоумышленник может подготовить свой собственный TPM и использовать любые полученные блобы учётных данных. Если он утерян, а все подготовленные устройства стали недоступны, учётные данные невозможно восстановить. Храните его как фразу восстановления аппаратного кошелька: офлайн, в безопасном месте, желательно с резервированием (например, разделённым на несколько мест).
Проект включает три взаимозаменяемых бэкенда:
webauthn_tpm_portable.py является основным бэкендом. Он формирует команды TPM на уровне байтов и работает как на Linux (/dev/tpmrm0), так и на Windows (TBS API через ctypes).
webauthn_tpm_linux.py использует библиотеку Python tpm2-pytss и работает только на Linux.
webauthn_soft.py — это чисто программная реализация, эмулирующая тот же формат учётных данных без TPM. Полезна для тестирования и разработки, но не обеспечивает аппаратной защиты.
"Permission denied" при обращении к /dev/tpmrm0:
Добавьте своего пользователя в группу tss и перелогиньтесь: sudo usermod -aG tss $USER
Ошибки импорта tpm2-pytss:
Попробуйте sudo apt install python3-tpm2-pytss или pip install --upgrade tpm2-pytss --break-system-packages.
Расширение не подключается к нативному хосту:
Проверьте, что path в манифесте нативного обмена сообщениями — это абсолютный путь к native_host.py. Откройте консоль браузера в Firefox (Ctrl+Shift+J), чтобы проверить ошибки расширения.
MIT
| Команда | Описание |
|---|
status | Проверить, подготовлен ли TPM |
provision --generate | Сгенерировать случайный сид и выполнить подготовку |
provision <seed_hex> | Подготовка с существующим сидом |
create <rp_id> | Создать учётные данные для проверяющей стороны |
sign <cred_id> <rp_id> <challenge> | Подписать вызов |
verify <cred_id> <rp_id> <challenge> <sig> | Проверить подпись |
clear | Удалить портативный родительский ключ из TPM |
test | Выполнить полный цикл create/sign/verify |