⚠️ 早期概念验证。 本项目尚未经过全面测试或审计。请勿将其用于实验之外的任何用途。
便携式、硬件支持的 WebAuthn/通行密钥凭证,使用 TPM 2.0 在多个设备上工作。
传统的TPM凭证被锁定在创建它们的设备上。本项目通过将确定性父密钥(从主种子派生)导入每个设备的TPM使其便携化。一个TPM加密的凭证blob可以被其他拥有相同种子的TPM加载和使用。私有签名密钥由TPM为每个凭证随机生成,且永远不会以明文形式存在于硬件之外。
主种子仅在每个设备配置时使用一次。此后,所有加密操作完全在TPM内部进行。
浏览器扩展覆盖 navigator.credentials,并通过原生消息将 WebAuthn 调用路由到直接与TPM通信的Python后端。
在注册时,TPM在便携父密钥下创建一个新的签名密钥,并返回一个加密的blob。在认证时,它重新加载blob,在内部解密,并对挑战进行签名。
Linux (Debian/Ubuntu):
sudo apt install tpm2-tools python3-tpm2-pytss python3-cryptography
Windows:
pip install cryptography
Windows 通过 ctypes 使用 TBS(TPM基础服务)与TPM通信,因此无需额外原生包。
浏览器扩展通过原生消息与 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)打开扩展弹窗,粘贴现有种子或点击“生成”创建新种子,然后点击“配置”。如果生成了新种子,请将其保存在安全的地方。您将需要它来配置其他设备,丢失它意味着将无法设置新设备(已配置设备上的现有凭证将继续工作)。
也可以从 CLI 进行配置:
./webauthn_cli.py provision --generate
# or with an existing seed:
./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。凭证ID中的加密blob在无法访问已配置的TPM时毫无用处。与基于软件的凭证存储不同,私钥在认证期间永远不会出现在主机内存中,这防止了冷启动攻击和基于恶意软件的密钥提取。
TPM2_Duplicate(理论上可以导出密钥)被阻止,因为凭证是使用空 authPolicy 创建的,即使拥有完全系统访问权限也无法复制。
在已配置系统上运行的恶意软件可以要求TPM对挑战进行签名,因为没有用户验证(没有按钮按下或生物识别)。它无法提取密钥,但可以在活动时使用它们。这比基于软件的凭证存储的攻击面更窄,因为恶意软件可以直接窃取密钥。
主种子是信任的根源。如果被泄露,攻击者可以配置自己的TPM并使用他们获得的任何凭证blob。如果丢失且所有已配置设备不可用,凭证将无法恢复。请像保存硬件钱包恢复短语一样保存它:离线,存放在安全位置,最好有冗余(例如分布在多个位置)。
该项目包含三个可互换的后端:
webauthn_tpm_portable.py 是主要后端。它在字节级别构建TPM命令,并可在Linux(/dev/tpmrm0)和Windows(通过ctypes的TBS API)上工作。
webauthn_tpm_linux.py 使用 tpm2-pytss Python库,仅适用于Linux。
webauthn_soft.py 是一个纯软件实现,模拟相同的凭证格式,无需TPM。对测试和开发有用,但不提供硬件保护。
对 /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 | 运行完整的创建/签名/验证循环 |