Questa pagina è stata tradotta automaticamente. Leggi la versione originale in inglese qui.

Cheatsheet Passkeys. Guide pratiche, pattern di distribuzione e KPI per programmi passkey.
Fornire un'autenticazione utente sicura e semplice è un requisito fondamentale per le aziende digitali nel 2024. Le passkey, come nuovo standard di accesso, sono la soluzione ideale per soddisfare queste esigenze. Tuttavia, l'esperienza utente e la sicurezza migliorate delle passkey per l'utente hanno un prezzo quando si tratta di implementarle come sviluppatore. La difficoltà di implementazione deriva dal fatto che le passkey sono relativamente nuove, non solo per gli utenti, ma anche per gli sviluppatori, e la loro implementazione può essere piuttosto impegnativa rispetto all'autenticazione basata su password. Infatti, sono necessari almeno quattro endpoint API per l'autenticazione tramite passkey rispetto a un endpoint API per l'autenticazione tramite password.
Uno dei componenti principali lato server per fornire l'autenticazione tramite passkey è il server WebAuthn (la parte verde della libreria). Per una guida completa su come il server WebAuthn si inserisce nella più ampia integrazione dello stack aziendale, consulta il nostro articolo dedicato.
Fonte: Yubico
In questo post del blog confrontiamo diverse librerie / pacchetti / SDK per server WebAuthn, analizziamo le differenze e forniamo una raccomandazione per gli sviluppatori che sono nuovi all'implementazione delle passkey.
Articoli recenti
Per capire meglio perché è necessaria una libreria server WebAuthn in primo luogo, diamo un'occhiata a come possono essere implementate le passkey. In linea di principio, ci sono due modi per integrare le passkey in siti web e app:
Mentre una soluzione per passkey di terze parti è facile da integrare e di solito fa risparmiare molto tempo di ingegneria (soprattutto per i casi limite, la manutenzione, il recupero, le soluzioni di fallback e il miglioramento della UX delle passkey), alcuni sviluppatori preferiscono implementare tutto da soli.
Prova le passkey in una demo live.
Diamo un'occhiata a come funziona l'implementazione delle passkey fai-da-te. In una configurazione di base, è necessario un meccanismo per la registrazione (sign-up) e l'autenticazione (login). Entrambi i processi, chiamati anche cerimonie WebAuthn, sono gestiti in modo diverso, anche se il flusso complessivo segue uno schema simile:
Poiché ogni processo di registrazione / accesso comporta questi passaggi, il backend deve tenere traccia degli utenti, delle passkey e delle richieste di registrazione / accesso.
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
We hit 80% mobile passkey activation across 5M+ users without replacing our IDP.
See how VicRoads scaled passkeys to 5M+ users — alongside their existing IDP.
Read the case studySe vuoi acquisire conoscenze più approfondite sul modo in cui funzionano le passkey e su come si presenta una semplice implementazione (senza utilizzare una soluzione per passkey di terze parti), puoi consultare il nostro articolo del blog qui.
Negli scenari reali, quando implementi le passkey da solo, tieni presente che non si tratta solo di fornire gli endpoint API necessari e l'implementazione di base per registrarsi e accedere. Oltre a ciò, è necessario affrontare i seguenti argomenti e casi d'uso:
Tuttavia, per l'implementazione di base delle passkey, è sufficiente aderire allo standard WebAuthn. L'implementazione di una libreria server WebAuthn ben nota e supportata di solito è sufficiente. La libreria genera i parametri del server WebAuthn e verifica le challenge di accesso, facendosi essenzialmente carico della parte crittografica e più complessa per te.
Entra nella nostra community passkeys per aggiornamenti e supporto.
Tutte le librerie server WebAuthn analizzate forniscono le funzionalità necessarie per offrire l'autenticazione tramite passkey. Pertanto, abbiamo prestato particolare attenzione ai seguenti criteri:
Sono state analizzate le seguenti librerie server WebAuthn (ordinate per numero decrescente di stelle su GitHub a dicembre 2023):
Scopri quante persone usano davvero le passkey.
type UserModel = { id: string; username: string; currentChallenge?: string; }; /** * It is strongly advised that authenticators get their own DB * table, ideally with a foreign key to a specific UserModel. * * "SQL" tags below are suggestions for column data types and * how best to store data received during registration for use * in subsequent authentications. */ type Authenticator = { // SQL: Encode to base64url then store as `TEXT`. Index this column credentialID: Uint8Array; // SQL: Store raw bytes as `BYTEA`/`BLOB`/etc... credentialPublicKey: Uint8Array; // SQL: Consider `BIGINT` since some authenticators return atomic timestamps as counters counter: number; // SQL: `VARCHAR(32)` or similar, longest possible value is currently 12 characters // Ex: 'singleDevice' | 'multiDevice' credentialDeviceType: CredentialDeviceType; // SQL: `BOOL` or whatever similar type is supported credentialBackedUp: boolean; // SQL: `VARCHAR(255)` and store string array as a CSV string // Ex: ['usb' | 'ble' | 'nfc' | 'internal'] transports?: AuthenticatorTransport[]; };
public class StoredCredential { /// <summary> /// The Credential ID of the public key credential source. /// </summary> public byte[] Id { get; set; } /// <summary> /// The credential public key of the public key credential source. /// </summary> public byte[] PublicKey { get; set; } /// <summary> /// The latest value of the signature counter in the authenticator data from any ceremony using the public key credential source. /// </summary> public uint SignCount { get; set; } /// <summary> /// The value returned from getTransports() when the public key credential source was registered. /// </summary> public AuthenticatorTransport[] Transports { get; set; } /// <summary> /// The value of the BE flag when the public key credential source was created. /// </summary> public bool IsBackupEligible { get; set; } /// <summary> /// The latest value of the BS flag in the authenticator data from any ceremony using the public key credential source. /// </summary> public bool IsBackedUp { get; set; } /// <summary> /// The value of the attestationObject attribute when the public key credential source was registered. /// Storing this enables the Relying Party to reference the credent’al's attestation statement at a later time. /// </summary> public byte[] AttestationObject { get; set; } /// <summary> /// The value of the clientDataJSON attribute when the public key credential source was registered. /// Storing this in combination with the above attestationObject item enables the Relying Party to re-verify the attestation signature at a later time. /// </summary> public byte[] AttestationClientDataJson { get; set; } public List<byte[]> DevicePublicKeys { get; set; } public byte[] UserId { get; set; } public PublicKeyCredentialDescriptor Descriptor { get; set; } public byte[] UserHandle { get; set; } public string AttestationFormat { get; set; } public DateTimeOffset RegDate { get; set; } public Guid AaGuid { get; set; } }
<?php declare(strict_types=1); namespace App\Entity; use App\Repository\PublicKeyCredentialSourceRepository; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\Uuid; use Webauthn\PublicKeyCredentialSource as BasePublicKeyCredentialSource; use Webauthn\TrustPath\TrustPath; #[ORM\Table(name: 'pk_credential_sources')] #[ORM\Entity(repositoryClass: PublicKeyCredentialSourceRepository::class)] class PublicKeyCredentialSource extends BasePublicKeyCredentialSource { #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public readonly DateTimeImmutable $createdAt; #[ORM\Id] #[ORM\Column(type: Types::STRING, length: 255)] #[ORM\GeneratedValue(strategy: 'NONE')] private string $id; public function __construct( string $publicKeyCredentialId, string $type, array $transports, string $attestationType, TrustPath $trustPath, AbstractUid $aaguid, string $credentialPublicKey, string $userHandle, int $counter ) { $this->id = Uuid::v4()->toRfc4122(); $this->createdAt = new DateTimeImmutable(); parent::__construct($publicKeyCredentialId, $type, $transports, $attestationType, $trustPath, $aaguid, $credentialPublicKey, $userHandle, $counter); } public function getId(): string { return $this->id; } }
La seguente tabella fornisce una panoramica delle librerie server WebAuthn:
Iscriviti al nostro Substack sulle passkey per le ultime novità.
Poiché la maggior parte delle librerie è ugualmente potente e implementa lo standard WebAuthn, raccomandiamo il seguente albero decisionale:
Se vuoi solo saperne di più sui server WebAuthn in generale senza avere già un progetto specifico, possiamo farti alcune raccomandazioni poiché ci sono alcune differenze tra le librerie e il loro materiale supplementare come documentazione ed esempi di implementazione. Quindi, per gli sviluppatori software desiderosi di avviare il loro percorso di implementazione delle passkey, consigliamo di scegliere le seguenti implementazioni:
Per una comprensione ancora più approfondita di come funziona WebAuthn lato server, puoi leggere la sezione molto dettagliata sulle operazioni della Relying Party di WebAuthn nella RFC di WebAuthn, che descrive in dettaglio ogni fase da implementare per la registrazione di una nuova credenziale (7.1) e la verifica di un'asserzione di autenticazione (7.2).
Valuta i tuoi requisiti specifici per le passkey e WebAuthn. In questo post del blog, abbiamo ipotizzato che tu voglia supportare solo le passkey come discoverable credentials. Leggi informazioni sulle PublicKeyCredentialCreationOptions e sulle PublicKeyCredentialRequestOptions insieme alle chiamate API WebAuthn lato client navigator.credentials.create() e navigator.credentials.get() per impostare correttamente i parametri nella configurazione dell'SDK del server WebAuthn per il tuo caso d'uso.
Per tutte le librerie server WebAuthn, dovrai fornire la struttura del database appropriata per persistere / accedere alle seguenti informazioni:
Per alcune librerie, ci sono raccomandazioni ed esempi specifici (se li abbiamo trovati utili, li abbiamo forniti sopra). È essenziale capire appieno quali campi WebAuthn devono essere memorizzati dove. Presta particolare attenzione per identificare quale valore desideri utilizzare per l'ID utente (user.id). Abbiamo una spiegazione più dettagliata qui. Tieni anche in considerazione cosa succede quando un utente potrebbe eliminare una passkey. Oltre a ciò, puoi facoltativamente limitare l'uso di determinati autenticatori. Un elenco di autenticatori validi correlati alle passkey può essere trovato qui. Nel caso in cui tu voglia anche supportare e controllare le attestazioni delle chiavi di sicurezza, questa è un'altra storia. Puoi trovare maggiori informazioni qui.
Identifica su quali dispositivi i tuoi utenti utilizzeranno le passkey e i metodi di autenticazione di fallback. Nel caso in cui tu non sia sicuro di quali dispositivi, browser e sistemi operativi utilizzino i tuoi utenti, dai un'occhiata allo State of Passkeys per i dati più recenti sulla prontezza per le passkey su piattaforme, browser e sistemi operativi. Se hai domande specifiche sull'adozione delle passkey e sulla quota di prontezza per le passkey di determinati dispositivi, non esitare a contattarci. Saremo lieti di fornirti ulteriori approfondimenti e aiutarti su questo argomento (vedi anche il nostro ultimo post sul blog riguardante la prontezza per le passkey). Dal punto di vista dell'osservabilità, mantieni i fallimenti WebAuthn lato client e i rifiuti di verifica del server come flussi separati; per le definizioni dei bucket lato client, utilizza gli errori WebAuthn. Inoltre, dovresti tenere presente che per Windows 10 e Linux dovrai trovare soluzioni dedicate poiché questi sistemi operativi forniscono il minor supporto per le passkey (se del caso).
Scopri quante persone usano davvero le passkey.
Per quasi ogni linguaggio o framework là fuori esiste ormai una libreria server WebAuthn ben consolidata. Il confronto tra le librerie di diversi linguaggi non mostra alcuna chiara superiorità di determinate implementazioni. Piuttosto, dovresti utilizzare il framework / linguaggio di programmazione con cui hai più familiarità. In alternativa, se non vuoi implementare WebAuthn tu stesso e prenderti cura di tutto ciò che ne consegue, puoi provare una soluzione dedicata e pre-costruita per l'autenticazione tramite passkey come Corbado. Ponendosi come una soluzione di autenticazione all-in-one incentrata sulle passkey, è dotata di un'eccellente passkey intelligence, gestione delle sessioni e metodi di autenticazione di fallback, in modo che tu possa concentrarti sullo sviluppo del tuo prodotto e dimenticarti dell'autenticazione. Puoi provarla gratuitamente con un numero illimitato di utenti qui.
Corbado è la Authentication Intelligence Platform per i team CIAM che gestiscono l'autenticazione consumer su larga scala. Ti aiutiamo a vedere ciò che i log IDP e gli strumenti di analytics generici non mostrano: quali dispositivi, versioni di OS, browser e gestori di credenziali supportano i passkey, perché gli enrollment non si trasformano in login, dove il flusso WebAuthn fallisce e quando un aggiornamento di OS o browser interrompe silenziosamente il login — tutto senza sostituire Okta, Auth0, Ping, Cognito o il tuo IDP interno. Due prodotti: Corbado Observe aggiunge osservabilità per i passkey e qualsiasi altro metodo di login. Corbado Connect introduce passkey gestiti con analytics integrato (insieme al tuo IDP). VicRoads gestisce i passkey per oltre 5M di utenti con Corbado (+80 % di attivazione passkey). Parla con un esperto di Passkey →
Per prima cosa controlla se esiste una libreria per il tuo framework specifico, poi per il tuo linguaggio di programmazione. Poiché tutte le librerie elencate implementano lo standard WebAuthn allo stesso modo, la scelta dovrebbe privilegiare la familiarità con il tuo stack esistente piuttosto che le differenze di funzionalità tra le librerie.
Come minimo devi conservare credenziali, utenti, challenge e autenticatori. Presta molta attenzione a quale valore assegni come ID utente (userHandle) e pianifica gli scenari in cui gli utenti potrebbero eliminare una passkey dal proprio dispositivo.
Le librerie server WebAuthn gestiscono le operazioni crittografiche più complesse: generare i parametri PublicKeyCredentialCreationOptions e PublicKeyCredentialRequestOptions e verificare le challenge firmate. Fare questo in modo corretto da zero è significativamente più difficile rispetto all'uso di una libreria conforme a FIDO che è già stata testata e sottoposta ad audit.
Windows 10 e Linux offrono il minor supporto per le passkey, quindi sono necessarie soluzioni di fallback dedicate per gli utenti su queste piattaforme. Monitorare i fallimenti WebAuthn lato client e i rifiuti di verifica del server come flussi separati aiuta a identificare i problemi specifici del sistema operativo in produzione.
Scopri come Corbado si integra con la tua distribuzione di passkey e con lo stack di autenticazione esistente.
Esplora la Console
Articoli correlati
Indice