SSO, WebAuthn en passkeys

Federation en Single Sign-On (SSO)

Bij cryptografie wordt het ten stelligste afgeraden om zomaar op de wilde boef een eigen crypto-algoritme te ontwikkelen. De kans dat je fouten met verstrekkende gevolgen maakt is te groot. Ook bij het omgaan van logindata van gebruikers en hoe je ze authenticeert is het aangeraden om even te bezinnen voor je er zelf aan begint.

Wat is Single Sign-On (SSO)?

Single Sign-On (SSO) is een authenticatiemethode waarbij een gebruiker zich éénmaal aanmeldt en vervolgens automatisch toegang krijgt tot meerdere applicaties of diensten, zonder zich bij elk systeem apart te moeten aanmelden. Je kent dit waarschijnlijk al: wanneer je inlogt op je Google-account, heb je meteen ook toegang tot Gmail, YouTube, Google Drive en tientallen andere Google-diensten - zonder telkens opnieuw je wachtwoord in te voeren. Dat is SSO in actie.

Het basisprincipe is eenvoudig: in plaats van dat elke applicatie zelf verantwoordelijk is voor authenticatie, wordt dit uitbesteed aan een centrale identity provider (IdP). Die identity provider bevestigt de identiteit van de gebruiker, waarna de applicatie (de service provider) de gebruiker vertrouwt op basis van die bevestiging.

Federation

Dankzij het concept federation kan SSO ook werken over de grenzen van organisaties heen. Gebruikers kunnen inloggen op jouw site of app (de service provider) gebruik makend van hun bestaande Google, Facebook of andere accounts. Een third-party (die jij en je gebruiker vertrouwen) zorgt dan voor de eigenlijke authenticatie als identity provider. Zo hoef je als ontwikkelaar niet wakker te liggen van hoe je gebruikerswachtwoorden gaat opslaan.

Een vereenvoudigd single sign-on proces.

Een vereenvoudigd single sign-on proces.

Federation via SSO is een onderdeel van federated identity management, een groep technologieën en concepten die ervoor zorgen dat de identiteit van een gebruiker over meerdere, onafhankelijke systemen wordt bewaard en gebruikt. Je zal de termen delegation en federation soms door elkaar zien tegenkomen wanneer je meer informatie over SSO opzoekt.

Samengevat gaan we bij delegation een gebruiker verplichten in te loggen met een bepaalde third-party die dit ondersteunt (bv. inloggen met je Facebook account). Bij federation gaat het breder: je website zal éénder welke third-party account aanvaarden, zolang deze maar compatibel is met het authenticatie systeem van je website (een voorbeeld hiervan is OpenID).

Enkele van de vele typische SSO knoppen die je geregeld zal tegenkomen.

Enkele van de vele typische SSO knoppen die je geregeld zal tegenkomen.
Tip

OAuth (open authorization) is een gestandaardiseerde manier om aan authenticatie te doen.

Uiteraard moeten we bij federatie benadrukken dat ook hier privacy een belangrijk aspect wordt. De vraag is dan ook in hoeverre je een bedrijf zoals Google of Facebook/Meta vertrouwt met jouw (login)data.

WebAuthn en passkeys

Een nieuwe technologie die in opmars is, is WebAuthn. Deze technologie laat toe om in te loggen op websites zonder dat je een wachtwoord moet ingeven. In plaats daarvan gebruik je een authenticator die je bij je hebt, zoals een USB-sleutel of je smartphone. Deze authenticator zal een digitale handtekening genereren die de website kan controleren.

Passkeys combineren de kracht van asymmetrische/public-key crypto en hardware authenticatie, met als grootste pluspunt dat gebruikers geen complexe wachtwoorden meer moeten onthouden.

Zonder in de ontstaansgeschiedenis te duiken, is het toch nuttig even enkele termen in vet te zetten die je zeker zal tegenkomen als je meer over passkeys wilt leren:

  • FIDO Alliance: de organisatie die de standaarden voor WebAuthn en U2F beheert. FIDO staat voor Fast IDentity Online.
  • WebAuthn (Web Authentication API): een API die websites toelaat om met authenticators te communiceren.
  • FIDO2: een standaard die WebAuthn ondersteunt, ontwikkel door de FIDO Alliance.
  • U2F (Universal 2nd Factor): een oudere standaard die ook door WebAuthn wordt ondersteund.
Tip

Op youtu.be/cEhc6vMFTh4 vind je een heel duidelijk overzicht van passkeys, inclusief de technische zijde ervan.

Een Passkey aanmaken: de registratie

Een passkey aanmaken is een eenvoudig proces. Je hebt een authenticator nodig, zoals een USB-sleutel of je smartphone. De authenticator zal een paar sleutels genereren: een public key en een private key. De public key wordt naar de website gestuurd, terwijl de private key (het wachtwoord met andere woorden) op de authenticator blijft.

Wanneer je dus als gebruiker registreert op een website of app, dan zal de passkey generatie van start gaan, als volgt:

  1. Bij het registreren kiest de gebruiker ervoor om een passkey te gebruiken (i.p.v. het klassieke wachtwoord).
  2. De gebruiker zal op zijn eigen toestel zichzelf nu eerst moeten identificeren. Dat kan op verschillende manieren: fingerprint scan, een PIN-code, een hardwaresleutel (denk aan bijvoorbeeld aan YubiKey), etc.
  3. Het toestel van de gebruiker genereert een sleutelpaar. De private sleutel blijft op het toestel en wordt veilig bewaard, de public sleutel wordt naar de website gestuurd.

Stap 3 gaan we even verder uit de doeken doen: we gaan natuurlijk deze sleutel niet zomaar over den draad versturen. We gaan natuurlijk onze kennis van certificaten gebruiken, die ons toelaten om te bewijzen dat de publieke wel degelijk de onze. De gebruiker zal zijn publieke sleutel verpakken in een attestation object: de publieke sleutel, samen met een signed challenge (zie verder), een credential ID en een certificaat. Dit attestation object wordt naar de andere zijde gestuurd, die deze zal bewaren.

De tegenpartij, bijvoorbeeld de website waar je wilt registreren, heeft uiteraard nog bewijs nodig dat het jouw attestation object wel kan vertrouwen. Tijdens stap 1 van de registratie zal de server daarom een challenge sturen, die de gebruiker mee in het attestation object moet plaatsen.

In dit hele proces heeft de website nooit toegang tot de private sleutel van de gebruiker. De website kan enkel de public sleutel zien en gebruiken. Het concept “het wachtwoord verlaat nooit het apparaat” wordt hier dus erg letterlijk genomen.

Waarschuwing

Doordat deze private sleutels niet meer op de website worden bewaard, wordt het gebruik van password managers nog belangrijker. De private sleutels worden immers opgeslagen op de authenticator, en als je die lange, complexe stukken data verliest, ben je al je accounts kwijt.

Een password manager kan je helpen om je accounts te beheren en je private sleutels (je passkeys, in dit geval zijn dit synced passkeys, een concept dat ook mee in WebAuthn is ingebouwd) veilig te bewaren én te synchroniseren naar je andere apparaten. I

Inloggen met een Passkey

Het inloggen met een passkey is gebaseerd op wat we weten uit public key crypto: je publieke sleutel kan je aan iedereen geven, enkel de houder van de bijhorende private sleutel zal de data kunnen lezen die met deze publieke sleutel werd geëncrypteerd.

De login-fase is dan ook bijna het zelfde als de registratie. Ook nu zal de gebruiker een challenge krijgen. Deze challenge zal de gebruiker nu encrypteren met z’n private sleutel. Wanneer de server deze geëncrypteerde challenge kan decrypteren met de bewaarde publieke sleutel van de gebruiker, weet deze dat de gebruiker mag toegelaten worden.

Het login proces met een passkey

Het login proces met een passkey

Authenticator apps en TOTP

Wanneer je multifactor authenticatie inschakelt op een website, krijg je vaak de keuze om een authenticator app te gebruiken, zoals Google Authenticator, Microsoft Authenticator of Authy. Deze apps genereren om de 30 seconden een nieuwe zescijferige code die je moet invoeren naast je wachtwoord. Maar hoe werkt dit? Hoe kan een app op jouw telefoon, die op dat moment geen internetverbinding nodig heeft, dezelfde code genereren als de server verwacht?

Het antwoord is een slim algoritme genaamd TOTP: Time-based One-Time Password.

De gedeelde geheime sleutel

Het hele systeem steunt, zoals zoveel in cryptografie, op een gedeelde geheime sleutel (shared secret). Wanneer je een authenticator app koppelt aan een website, gebeurt het volgende:

  1. De website genereert een willekeurige geheime sleutel (typisch 160 bits).
  2. Deze sleutel wordt aan jou getoond, meestal in de vorm van een QR-code die je scant met je authenticator app.
  3. Zowel de server als jouw app bewaren nu dezelfde geheime sleutel.

Dit is het enige moment waarop de sleutel wordt uitgewisseld. Vanaf nu hoeven jouw telefoon en de server nooit meer rechtstreeks met elkaar te communiceren om geldige codes te genereren.

Waarschuwing

Omdat de QR-code de volledige geheime sleutel bevat, moet je deze met de nodige voorzichtigheid behandelen. Maak er geen screenshot van die je onbeveiligd bewaart en toon de code niet aan anderen. Wie de geheime sleutel heeft, kan dezelfde codes genereren als jij.

Hoe TOTP werkt

TOTP combineert twee ingrediënten om een code te genereren:

  1. De gedeelde geheime sleutel (die zowel de app als de server kennen).
  2. De huidige tijd, afgerond naar blokken van 30 seconden.

Het algoritme werkt als volgt:

  1. Neem de huidige Unix-tijd (het aantal seconden sinds 1 januari 1970) en deel deze door 30. Rond af naar beneden. Dit geeft een getal dat we de tijdstap (time step) noemen. Gedurende diezelfde 30 seconden zullen jouw telefoon én de server exact dezelfde tijdstap berekenen.
  2. Gebruik nu een HMAC (Hash-based Message Authentication Code) om de geheime sleutel te combineren met deze tijdstap. Het resultaat is een lange hash.
  3. Uit deze hash wordt via een vaste procedure (dynamic truncation) een zescijferig getal geëxtraheerd: de code die je op je scherm ziet.

Omdat zowel de server als jouw app dezelfde geheime sleutel en dezelfde tijd gebruiken, genereren ze onafhankelijk van elkaar dezelfde code. Na 30 seconden verandert de tijdstap en krijg je een volledig nieuwe code.

Tip

Servers accepteren meestal niet enkel de code van het huidige tijdsblok, maar ook die van het vorige en het volgende blok. Dit geeft een marge van ongeveer 90 seconden en vangt kleine klokverschillen op tussen jouw telefoon en de server.

Waarom is TOTP veilig?

TOTP biedt een aantal belangrijke voordelen:

  • Eenmalig: iedere code is slechts 30 seconden geldig. Zelfs als een aanvaller je code onderschept, is deze tegen de tijd dat hij deze wil gebruiken waarschijnlijk al vervallen.
  • Geen netwerkverbinding nodig: de app heeft na de initiële registratie geen internet meer nodig. De tijd is het enige dat de app en server synchroniseert.
  • Niet voorspelbaar: zonder kennis van de geheime sleutel is het onmogelijk om toekomstige codes te berekenen, zelfs als je vorige codes hebt gezien.
Waarschuwing

TOTP is niet onfeilbaar. Een aanvaller die erin slaagt om tegelijkertijd je wachtwoord én een geldige TOTP-code te bemachtigen (bijvoorbeeld via een real-time phishing aanval die als proxy fungeert tussen jou en de echte website) kan nog steeds inloggen. Passkeys (zie eerder) zijn in dat opzicht veiliger omdat ze gebonden zijn aan het specifieke domein van de website.

Samenvatting: drie gouden regels

We hebben in dit hoofdstuk veel technieken en protocollen behandeld, maar alles valt terug te brengen tot drie kernregels die een goed authenticatiesysteem steeds moet respecteren:

  1. Het wachtwoord mag nooit van de client naar de server gestuurd worden. (→ hashing, CRAM, SCRAM)
  2. Het wachtwoord mag nooit van de server naar de client gestuurd worden. (→ denk aan de “Ik ben m’n wachtwoord vergeten”-test)
  3. Het wachtwoord mag nooit in leesbare vorm op de server bewaard worden. (→ hashing + salting)

Moderne protocollen zoals passkeys gaan zelfs een stap verder: het wachtwoord (de private sleutel) verlaat zelfs de authenticator niet.