Door Redsandro:
Zou je kunnen zeggen dat een passkey een soort master password is die is opgeslagen in de secure enclave, [...]
Geen
master password: sterk vereenvoudigd is een passkey
gewoon een uniek, lang en niet te raden wachtwoord voor één online account - echter met de volgende 2 m.i. belangrijkste verschillen:
1) De kans dat je op een nepsite inlogt is véél kleiner, omdat de software checkt of de domeinnaam van de server hetzelfde is als waar jij ooit jouw account op aanmaakte;
2) Je hebt geen eigen beheer meer over jouw inloggegevens.
Dat was de korte uitleg. Voor geïnteresseerden leg ik hieronder (zo compact als ik kan, maar toch heel lang) uit hoe asymmetrische cryptografie, passkeys en certificaten werken (mede om het authenticeren met passkeys te kunnen vergelijken met client certificaten).
Nb. feitelijk bevatten FIDO2 hardware keys gewoon één of meer passkeys; beide systemen gebruiken hetzelde
WebAuthn protocol. Ik laat hier overigens veel details, waaronder attestation, weg.
Asymmetrische cryptografie
Digitale certificaten werken met "asymmetrische sleutelparen" waarbij elk paar bestaat uit een private key (die je strikt geheim houdt) en een public key die je met iedereen kunt delen (waarbij vaak vergeten of niet gesnapt wordt dat het loeibelangrijk is, om bedrog te voorkomen, dat je zeker weet van
wie een public key is).
Door een wiskundige truc geldt (er zijn veel mitsen en maren, maar de essentie is):
1) Wat je met de public key versleutelt, kun je
uitsluitend met de bijpassende private key ontsleutelen;
en vice versa:
2) Wat je met de private key versleutelt, kun je
uitsluitend met de bijpassende public key ontsleutelen.
Digitale handtekeningen
De genoemde tweede toepassing is de basis van digitale handtekeningen:
in theorie versleutel je bijvoorbeeld een koopakte met jouw private key. Iedereen die jouw public key heeft kan die versleutelde koopakte dan ontsleutelen. Als zij zeker weten dat de public key
van jou is én dat niemand anders jouw private key heeft, moet deze koopakte impliciet
door jou zijn ondertekend.
In de praktijk werken digitale handtekeningen iets anders: je berekent een
cryptografische hash over het te ondertekenen document (bijv. een digitale koopakte, effectief een reeks bytes). Vervolgens versleutel je die
cryptografische hash met jouw private key. De digitale handtekening bestaat dan uit de (met de private key)
versleutelde cryptografische hash, die samen met het (onversleutelde) document wordt verzonden.
Om de digitale handtekening te kunnen controleren moet de ontvanger over een public key beschikken
en zeker weten dat die public key van de verzender is (daarover zo meer).
Dan doet de ontvanger:
a) ontsleutel de versleutelde cryptografische hash met de public key van de ondertekenaar;
b) bereken zelf de cryptografische hash over het document;
c) als beide cryptografische hashes identiek zijn, klopt de (bijgevoegde) digitale handtekening.
Van WIE is die pubkey?
Hoe weet je nu zeker
van wie een public key is (d.w.z. wie de bijbehorende private key bezit)? Dat kan met een digitaal certificaat.
Digitale certificaten
De public key wordt, samen met informatie die uniek de eigenaar van het sleutelpaar beschrijft (bijv. een e-mailadres of een domeinnaam zoals "tweakers.net" bij een https servercertificaat) met allerlei metadata (waaronder geldigheidsduur en gebruiksdoel) opgenomen in een "certificaatverzoek".
Cert-uitgever: trusted third party
Nadat een certificaatuitgever heeft vastgesteld dat de public key
daadwerkelijk van de vermelde eigenaar is, zet
die certificaatuitgever een digitale handtekening onder dat certificaatverzoek, waarmee het verzoek een certificaat is geworden.
Effectief koppelt een certificaat een public key aan een unieke identiteitsbeschrijving.
Aanvulling 20221211 11:12: het bezitten en kunnen "tonen" (verzenden) van een certificaat (of losse public key) zegt
niets over de identiteit van de verzender. Bij elke transactie hoort
tevens het bezit van de bijpassende private key te worden aangetoond (op een manier die niet kwetsbaar is voor replay-attacks).
Van WIE is die pubkey? #2
Indien jij (d.w.z. de software die jij gebruikt) als ontvanger die certificaatuitgever vertrouwt, en zeker weet dat het certificaat echt door de kennelijke certificaatuitgever is ondertekend
en jij erop vertrouwt dat die certificaatuitgever z'n werk goed doet, weet je dus van wie de public key in dat certificaat is.
WebAuthn: passkeys en FIDO2
WebAuthn (gebruikt door FIDO2 hardware keys en passkeys) werkt
ook met asymmetrische sleutelparen, maar
zonder dat daar certificaten bij worden gebruikt. Als er een public key aan jouw account wordt toegevoegd, heeft de server geen bewijs dat die public key
van jou is (een aanvaller met toegang tot jouw account kan dus ook
zijn public key toevoegen en jou buitensluiten).
Daarmee zijn passkeys vooral geschikt voor consumenten. Client certificaten kunnen door werkgevers worden verstrekt, bijv. in smartcards of USB devices. Met client certs heb je een soort "absolute" authenticatie, terwijl je met WebAuthn een pseudoniem account kunt aanmaken (zoals velen doen op tweakers, en hoewel ik echt Erik van Straten heet, heb ik dat nergens bewezen - los van
welke Erik van Straten ik ben - ik heb naamgenoten).
Passkey account maken
Aanmaken van een account met passkey gaat op vergelijkbare wijze als met een wachtwoord, en toevoegen van een passkey aan een bestaand account kun je vergelijken met het toevoegen van een gangbare 2FA methode. Ik ga hier niet verder in op de details.
Inloggen met passkey
Bij inloggen heeft een passkey twee belangrijke voordelen:
1) De software (server + client) checkt, redelijk betrouwbaar (veel betrouwbaarder dan veel mensen doen, maar iets minder betrouwbaar dan kan met een client certificaat) of de in de adresbalk van jouw browser getoonde domeinnaam
van de door jou bedoelde server is (waar je ooit het account hebt aangemaakt). Daarmee is het voor aanvallers veel lastiger om mensen te foppen met "evil proxy" aanvallen, meestal met "lijkt-op" domeinnamen zoals
microsoft-sso.net of
accounts-google.com (hoe die "evil proxy" aanvallen werken, leg ik
hier uit).
Daarmee zijn passkeys
aanzienlijk veiliger dan andere vormen van MFA/2FA, zoals TOTP met "Authenticator" apps (ook number matching helpt niet tegen evil proxies!) en OTP (o.a. via SMS).
2) Nogal gehyped maar m.i. nauwelijks relevant als mensen per account een uniek wachtwoord zouden gebruiken: als de server gehacked wordt hebben de aanvallers bijna niets aan de public key van jouw passkey die op de server staat (wel hebben ze toegang tot al jouw
data op die server, en dat is nou net wat we met inloggen proberen te verhinderen).
Werking van passkeys
Bij inloggen werkt een passkey, vereenvoudigd, als volgt:
a) Om te laten weten
wie er wil inloggen, stuur jij een identifier (vaak jouw e-mailadres) naar de server.
b) De server zoekt de gegevens van jouw account op, en als je een passkey wilt gebruiken, stuurt de server een "nonce" (een uniek lang, meestal willekeurig, getal) naar de client.
c) Voordat de client naar een passkey- (WebAuthn-) record voor de in de adresbalk van jouw browser getoonde domeinnaam mag zoeken in de secure enclave (of hardware key), moet je met biometrie of een pincode bewijzen dat jij niet iemand anders bent.
d) De client zoekt daarna in de secure enclave (of hardware key) naar een WebAuthn-record met een domeinnaam die gelijk is aan,
of eindigt op (met een punt ertussen!), de domeinnaam in de adresbalk van de browser. Nb. dit is de
éérste WebAuthn serverdomeinnaam-check.
Voorbeeld: als je een passkey hebt voor
google.com, worden dus ook
accounts.google.com en
sites.google.com geaccepteerd - maar niet
accounts-google.com.
e) De client plakt de nonce en het in de adresbalk getoonde
origin (
https://domeinnaam:poortnummer waarbij "
:poortnummer" optioneel is) achter elkaar, en zet daar (in de secure enclave of hardware key, met de private key uit het gevonden passkey-record) een digitale handtekening onder. Vervolgens stuurt de client dat pakketje ter authenticatie van jou naar de server.
f) De server checkt de digitale handtekening met de public key van jouw passkey in jouw accountgegevens (als die klopt weet de server dat jij de bijpassende private key hebt).
Belangrijk: de server hoort
ook te controleren of de ontvangen nonce gelijk is aan de eerder door de server verzonden nonce (om "replay attacks" te voorkomen)
én de server hoort te checken of jij met een passkey (of hardware key) daadwerkelijk mag inloggen op het meegestuurde
origin (dit is de
tweede check op de serverdomeinnaam).
Reden voor die tweede check: een aanvaller zou een evil proxy login pagina op
sites.google.com kunnen maken en jou verleiden daarop in te loggen, waarmee die aanvaller vervolgens
als jou kan inloggen op
accounts.google.com.
Nb. ik heb persoonlijk contact gehad met Google om het beschreven scenario uit te sluiten; Google zegt hun inlogservers strikt te laten checken op
welke subdomeinen je mag inloggen (
dat zijn er overigens meerdere).
g) Als alles klopt stuurt de server een session-cookie naar jouw browser, waarmee je vanaf dat moment bij elke transactie (1FA!) authenticeert (tot je uitlogt of wordt uitgelogd).
Enkele WebAuthn risico's
Naast het risico dat servers niet goed op subdomeinen checken (denk aan subdomain-takeover attacks) valt en staat WebAuthn met de betrouwbaarheid van https servercertificaten. Als een MitM/AitM (Man/Attacker in the Middle), bijvoorbeeld via een DNS-record-hack of een
BGP hijack een geldig certificaat kan verkrijgen, kan daarmee een "evil proxy" worden gecreëerd.
Bij client-certificaten bestaat dit AitM-risico
niet (mits de server de juiste TLS-checks uitvoert). Het "nadeel" van client certs is dat
geen enkele AitM is toegestaan: als firewalls en/of virusscanners "TLS-inspectie" op het inlogproces uitvoeren, slaagt dit niet (WebAuthn heeft hier dan weer geen last van).
Een ander risico is dat mensen, die nog geen passkey gebruiken, met phishing-aanvallen worden verleid om een passkey toe te voegen op een nepserver (evil proxy). De aanvaller logt dan onmiddelijk met de verstrekte inloggegevens (indien nodig inclusief TOTP of OTP) op de echte inlogserver en voegt daar desgewenst zijn eigen passkey toe (en/of wijzigt het wachtwoord). De public key van de door het slachtoffer aangemaakte passkey kan de aanvaller gewoon weggooien.
Nog een groot probleem: vaak bestaat de mogelijkheid om, als alternatief, met een
phishable methode (evil proxy) in te loggen. Bijv. met een e-mail kan een aanvaller je naar een nepsite sturen waarop staat dat er een probleem is met jouw passkey of iets op de server, en je deze keer op alternatieve wijze moet inloggen.
Hier laat ik het maar even bij :-)
Aanvulling 20221210 14:28: in tegenstelling tot bij client-certificaten kun je WebAuthn credentials (passkeys in een gestolen smartphone of opgeslagen in een verloren hardware key) niet snel en eenvoudig
intrekken (revoken, er bestaat geen revocation methode).
[Reactie gewijzigd door ErikvanStraten op 11 december 2022 11:12]