
Portatili, credenziali WebAuthn supportate da hardware utilizzanti TPM 2.0. Chiave genitore deterministica derivata da un seed master consente la portabilità delle credenziali tra dispositivi. Le chiavi di firma private non lasciano mai il TPM. Include estensione per browser e CLI.
⚠️ Prova di concetto iniziale. Questo progetto non è stato testato o verificato approfonditamente. Non utilizzarlo per scopi diversi dalla sperimentazione.
Credenziali WebAuthn/passkey portatili, basate su hardware, che funzionano su più dispositivi utilizzando TPM 2.0.
Le credenziali TPM tradizionali sono bloccate sul dispositivo che le ha create. Questo progetto le rende portatili importando una chiave genitore deterministica (derivata da un seed principale) nel TPM di ogni dispositivo. I blob di credenziali crittografati da un TPM possono quindi essere caricati e utilizzati da qualsiasi altro TPM configurato con lo stesso seed. Le chiavi di firma private vengono generate casualmente dal TPM per ogni credenziale e non esistono mai in testo semplice al di fuori dell'hardware.
Il seed principale è necessario solo una volta per dispositivo durante il provisioning. Successivamente, tutte le operazioni crittografiche avvengono interamente all'interno del TPM.
Un'estensione del browser sovrascrive navigator.credentials e instrada le chiamate WebAuthn attraverso la messaggistica nativa verso un backend Python che comunica direttamente con il TPM. Durante la registrazione, il TPM crea una nuova chiave di firma sotto il genitore portatile e restituisce un blob crittografato. Durante l'autenticazione, carica nuovamente il blob, lo decrittografa internamente e firma la sfida.
Linux (Debian/Ubuntu):
sudo apt install tpm2-tools python3-tpm2-pytss python3-cryptography
Windows:
pip install cryptography
Windows comunica con il TPM tramite TBS (TPM Base Services) attraverso ctypes, quindi non sono necessari pacchetti nativi aggiuntivi.
L'estensione del browser comunica con native_host.py attraverso la messaggistica nativa. È necessario registrare un manifest che indichi a Firefox dove trovare l'host.
Crea il file ~/.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]"
]
}
Sostituisci path con il percorso assoluto di native_host.py. Assicurati che sia eseguibile (chmod +x native_host.py).
Su Windows, il manifest della messaggistica nativa viene registrato tramite il Registro di Windows. Vedi la documentazione di Firefox sulla messaggistica nativa per i dettagli.
cd extension
npm install
npm run build
Poi in Firefox:
about:debugging#/runtime/this-firefoxextension/dist (ad es. manifest.json)Apri il popup dell'estensione e incolla un seed esistente oppure clicca su "Genera" per crearne uno nuovo, quindi clicca su "Provision". Se generi un nuovo seed, salvalo in un posto sicuro. Ne avrai bisogno per preparare ulteriori dispositivi, e perderlo significa perdere la capacità di configurare nuovi dispositivi (le credenziali esistenti su dispositivi già preparati continueranno a funzionare).
Il provisioning può essere eseguito anche dalla CLI:
./webauthn_cli.py provision --generate
# or with an existing seed:
./webauthn_cli.py provision <seed_hex>
./webauthn_cli.py test
Questo crea una credenziale, firma una sfida e verifica la firma.
webauthn_cli.py [--backend=BACKEND] <command> [args]
Comandi:
Backend (selezionati con --backend o la variabile d'ambiente WEBAUTHN_BACKEND):
| Backend | Descrizione |
|---|---|
tpm | TPM multipiattaforma tramite comandi raw (predefinito) |
linux | Solo Linux, utilizza la libreria tpm2-pytss |
soft | Puramente software, nessun TPM richiesto (per test) |
Le chiavi di firma delle credenziali vengono generate all'interno del TPM e non lo lasciano mai in testo semplice. Il blob crittografato nell'ID della credenziale è inutile senza l'accesso a un TPM configurato. A differenza dei depositi di credenziali basati su software, le chiavi private non sono mai presenti nella memoria dell'host durante l'autenticazione, proteggendo dagli attacchi cold boot e dall'estrazione di chiavi basata su malware.
TPM2_Duplicate (che potrebbe teoricamente esportare chiavi) è bloccato perché le credenziali vengono create con un authPolicy vuoto, rendendo la duplicazione impossibile anche con accesso completo al sistema.
Il malware in esecuzione su un sistema configurato può chiedere al TPM di firmare le sfide, poiché non esiste verifica dell'utente (nessuna pressione di pulsante o biometria). Non può estrarre le chiavi, ma può usarle mentre è attivo. Questa è una superficie di attacco più ristretta rispetto ai depositi di credenziali basati su software in cui il malware può rubare le chiavi direttamente.
Il seed principale è la radice di fiducia. Se viene compromesso, un attaccante può preparare il proprio TPM e utilizzare qualsiasi blob di credenziali ottenuto. Se viene perso e tutti i dispositivi configurati diventano non disponibili, le credenziali sono irrecuperabili. Conservalo come faresti con una frase di recupero di un hardware wallet: offline, in un luogo sicuro, idealmente con ridondanza (ad es. suddiviso in più posizioni).
Il progetto include tre backend intercambiabili:
webauthn_tpm_portable.py è il backend principale. Costruisce comandi TPM a livello di byte e funziona sia su Linux (/dev/tpmrm0) che su Windows (API TBS tramite ctypes).
webauthn_tpm_linux.py utilizza la libreria Python tpm2-pytss e funziona solo su Linux.
webauthn_soft.py è un'implementazione puramente software che emula lo stesso formato di credenziali senza alcun TPM. Utile per test e sviluppo, ma non fornisce protezione hardware.
"Permesso negato" su /dev/tpmrm0:
Aggiungi il tuo utente al gruppo tss e riaccedi: sudo usermod -aG tss $USER
Errori di importazione di tpm2-pytss:
Prova sudo apt install python3-tpm2-pytss o pip install --upgrade tpm2-pytss --break-system-packages.
L'estensione non si connette all'host nativo:
Verifica che il path nel manifest della messaggistica nativa sia un percorso assoluto che punta a native_host.py. Apri la Console del Browser in Firefox (Ctrl+Shift+J) per controllare eventuali errori dall'estensione.
MIT
| Comando | Descrizione |
|---|
status | Controlla se il TPM è configurato |
provision --generate | Genera un seed casuale e prepara |
provision <seed_hex> | Prepara con un seed esistente |
create <rp_id> | Crea una credenziale per un relying party |
sign <cred_id> <rp_id> <challenge> | Firma una sfida |
verify <cred_id> <rp_id> <challenge> <sig> | Verifica una firma |
clear | Rimuove la chiave genitore portatile dal TPM |
test | Esegue un ciclo completo di creazione/firma/verifica |