mimi89999/webauthn_tpm_portable
GitHub: mimi89999/webauthn_tpm_portable
利用TPM 2.0实现可跨设备移植的硬件级WebAuthn/passkey凭证,私钥永不离开TPM。
Stars: 2 | Forks: 0
# WebAuthn TPM 可移植凭证
利用 TPM 2.0 实现的、可在多设备间使用的可移植、硬件级 WebAuthn/passkey 凭证。
传统的 TPM 凭证被锁定在创建它们的设备上。本项目通过向每个设备的 TPM 导入确定性父密钥(由主种子派生)来实现其可移植性。随后,由一个 TPM 加密的凭证 Blob 可以被任何其他配置了相同种子的 TPM 加载和使用。私有签名密钥由 TPM 为每个凭证随机生成,且从不在硬件外部以明文形式存在。
主种子仅在配置期间在每个设备上需要一次。此后,所有加密操作完全在 TPM 内部进行。
## 工作原理
浏览器扩展程序覆盖 `navigator.credentials`,并通过原生消息将 WebAuthn 调用路由到与 TPM 直接通信的 Python 后端。在注册时,TPM 在可移植父密钥下创建一个新的签名密钥并返回加密的 Blob。在身份验证时,它将 Blob 加载回来,在内部解密,并对挑战进行签名。
## 系统要求
- **操作系统:** Linux 或 Windows(macOS 没有 TPM)
- **硬件:** TPM 2.0
- **Python:** 3.10+
- **浏览器:** Firefox(计划支持 Chrome)
## 安装说明
### 1. 安装依赖
**Linux (Debian/Ubuntu):**
```
sudo apt install tpm2-tools python3-tpm2-pytss python3-cryptography
```
**Windows:**
```
pip install cryptography
```
Windows 通过 ctypes 使用 TBS (TPM Base Services) 与 TPM 通信,因此不需要额外的原生包。
### 2. 设置原生消息
浏览器扩展程序通过原生消息与 `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": [
"webauthn-tpm@lebihan.pl"
]
}
```
将 `path` 替换为指向 `native_host.py` 的绝对路径。确保它具有可执行权限(`chmod +x native_host.py`)。
在 Windows 上,原生消息清单是通过 Windows 注册表注册的。有关详细信息,请参阅 [Firefox 原生消息文档](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging)。
### 3. 加载浏览器扩展
```
cd extension
npm install
npm run build
```
然后在 Firefox 中:
1. 打开 `about:debugging#/runtime/this-firefox`
2. 点击 "Load Temporary Add-on..."
3. 选择 `extension/dist` 文件夹中的任何文件(例如 `manifest.json`)
### 4. 配置 TPM
打开扩展程序弹出窗口,粘贴现有种子或点击 "Generate" 创建新种子,然后点击 "Provision"。如果您生成新种子,**请将其保存在安全的地方**。您将需要它来配置其他设备,丢失它意味着失去设置新设备的能力(已配置设备上的现有凭证将继续工作)。
配置也可以通过 CLI 完成:
```
./webauthn_cli.py provision --generate
# 或使用现有的 seed:
./webauthn_cli.py provision
```
### 5. 验证
```
./webauthn_cli.py test
```
这将创建一个凭证,对挑战进行签名,并验证签名。
## CLI 参考
```
webauthn_cli.py [--backend=BACKEND] [args]
```
**命令:**
| 命令 | 描述 |
|---------|-------------|
| `status` | 检查 TPM 是否已配置 |
| `provision --generate` | 生成随机种子并进行配置 |
| `provision ` | 使用现有种子进行配置 |
| `create ` | 为依赖方创建凭证 |
| `sign ` | 对挑战进行签名 |
| `verify ` | 验证签名 |
| `clear` | 从 TPM 中移除可移植父密钥 |
| `test` | 运行完整的创建/签名/验证循环 |
**后端**(通过 `--backend` 或 `WEBAUTHN_BACKEND` 环境变量选择):
| 后端 | 描述 |
|---------|-------------|
| `tpm` | 通过原始命令实现跨平台 TPM(默认) |
| `linux` | 仅限 Linux,使用 `tpm2-pytss` 库 |
| `soft` | 纯软件,不需要 TPM(用于测试) |
## 安全性
### 受保护的内容
凭证签名密钥在 TPM 内部生成,且从不以明文形式离开 TPM。如果没有访问已配置的 TPM 的权限,凭证 ID 中的加密 Blob 是无用的。与基于软件的凭证存储不同,私有密钥在身份验证期间从不会出现在主机内存中,这可以防止冷启动攻击和基于恶意软件的密钥提取。
`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` 上的 "Permission denied":**
将您的用户添加到 `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
标签:CTAP, CVE, DNS枚举, FIDO2, Python, TPM 2.0, WebAuthn, 公钥加密, 凭证可移植性, 加密技术, 后端开发, 安全密钥, 数字签名, 数据加密, 数据可视化, 无后门, 无密码认证, 本地主机通讯, 浏览器扩展, 硬件安全模块, 网络安全, 网络安全工具, 跨设备凭证, 逆向工具, 通行密钥, 隐私保护, 零信任安全