Deze cursus werd gemaakt met hulp van AI-assistentie. Sommige afbeeldingen zijn door AI gegenereerd.
Wat leer je in dit hoofdstuk?
Na dit hoofdstuk kan je:
de drie gouden regels van wachtwoordbeheer toepassen
hashing, salting en rainbow tables uitleggen, en waarom salting beschermt
CRAM, SCRAM en passkeys onderling situeren
de vier MFA-factoren (weten, hebben, zijn, waar/wanneer) combineren
TOTP uitleggen, en waarom passkeys veiliger zijn tegen real-time phishing
Authenticatie vs autorisatie
Authenticatie
Wie ben je?
Het bewijs van je identiteit.
Autorisatie
Wat mag je?
Het toekennen van rechten.
Dit hoofdstuk focust op authenticatie: hoe gaan we als beheerders veilig om met login-informatie?
De geheime sleutel
Je wachtwoord is in essentie je geheime sleutel.
Login = gebruikersnaam + wachtwoord. Het weten van die sleutel is een eerste vorm van authenticatie. Als beheerder ga je er dus uitermate veilig mee om.
Deel 1 Veilige wachtwoorden
Veel hangt af van hoe gebruikers zelf met hun wachtwoorden omgaan.
Veilige wachtwoorden: de regels
Regels die continu niét gehanteerd worden:
Nooit hergebruiken
Eén wachtwoord per service.
Geen dictionary
Geen woorden uit dictionaries. Overweeg random gegenereerde wachtwoorden.
Lang genoeg
Minimum 16 tekens.
Gemengd
Cijfers, letters (groot én klein) en leestekens.
Hoe stropers aan wachtwoorden komen
Niet altijd via de database. Denk aan de McCumber kubus: technologie is maar één aspect.
Password spraying
Veelgebruikte wachtwoorden testen op veel accounts: “spray and pray”.
(Spear) phishing
Nep-mail of -bericht → malware of een fake login. Spear phishing is op maat, gericht op één doelwit.
Keyloggers
Alle toetsaanslagen opnemen en later analyseren.
Spear phishing is vandaag één van dé social engineering aanvallen bij uitstek.
Online vs. offline aanvallen
Online
Actief inloggen of het wachtwoord bij de bron onderscheppen
Password spraying, phishing, keyloggers
Offline
De aanvaller heeft (lees)toegang tot de wachtwoord-databank
Via SQL injection, een insider, een datalek, …
Ga er van uit dat het gebeurt
Je databank zal vroeg of laat lekken.
Vanaf nu sta je in de schoenen van de beheerder: hoe beperk je de schade bij zo’n lek tot een minimum?
Deel 2 Hoe wachtwoorden opslaan
We gaan bottom-up: van naïef naar veilig.
Van naïef naar veilig
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": true}} }%%
graph LR
A("Plaintext 🚫") --> B("Hashing")
B --> C("Hashing + Salting")
C --> D("CRAM / SCRAM")
style A fill:#ff4444,stroke:#333,color:#fff
style D fill:#44aa44,stroke:#333,color:#fff
Stap 1 Paswoorden als plaintext
Databank met twee kolommen: gebruikersnaam + wachtwoord
Het wachtwoord staat er zoals het is
Databank gestolen? Dan heeft de aanvaller alle wachtwoorden in handen.
User
Password
alice
welcome123
bob
qwerty
carol
password1
Belangrijk
Paswoorden mogen NOOIT als plaintext in een databank staan!
Hoe herken je plaintext-opslag?
Mail met je originele wachtwoord? Dan staat het er als plaintext.
Test het met de “Ik ben m’n wachtwoord vergeten”-knop. Een service zou jouw wachtwoord nooit mogen kunnen zien. Uiteindelijk mag je wachtwoord zelfs nooit je computer verlaten.
Facebook, 2019 Wie zou nu zo dom zijn?!
Wachtwoorden van honderden miljoenen gebruikers in plaintext bewaard.
200-600
miljoen gebruikers getroffen
~20.000
Facebook-medewerkers hadden toegang
jaren
bleef het onopgemerkt
Stap 2 Paswoord hashing
De client berekent lokaal de hash van het wachtwoord
Enkel de hash gaat over het netwerk
De server vergelijkt met de hash in de database
Gelijk? Dan kende de gebruiker het juiste wachtwoord.
Hashing flow
%%{init: {"theme": "base", "sequence": {"useMaxWidth": true}} }%%
sequenceDiagram
participant U as 👤 Gebruiker
participant C as 💻 Client
participant S as 🖥️ Server
participant DB as 🗄️ Database
U->>C: typt wachtwoord
C->>C: hash(wachtwoord)
C->>S: gebruikersnaam + hash
S->>DB: zoek opgeslagen hash
DB-->>S: opgeslagen hash
S->>S: vergelijk hashes
S-->>C: ✅ Toegang (indien gelijk)
Het gevaar van hashing
Hashing is vatbaar voor een pass-the-hash aanval.
Een geldige gebruikersnaam + hash capteren volstaat om in te loggen. Het originele wachtwoord kennen hoeft niet.
Pass-the-hash aanval
Geen kraakwerk nodig
De aanvaller hoeft het originele wachtwoord nooit te kraken: de hash zelf is genoeg om zich aan te melden.
Probleem met hashing
Een secure hash is niet omkeerbaar. Toch kan dit gebeuren:
Collisions
Twee verschillende wachtwoorden → dezelfde hash.
Hergebruik
Twee gebruikers met hetzelfde wachtwoord → dezelfde hash.
Oplossing: salting (zie verder).
Veel websites hashen wel aan serverzijde, maar dan over een beveiligde TLS-tunnel.
Rainbow table attack: het dilemma
Databank gestolen? Dan moet de aanvaller de hashes nog kraken.
Ter plekke hashen
bcrypt, scrypt en pbkdf2 zijn by design traag
→ timebottleneck
Vooraf precomputen
Alle mogelijke hashes op voorhand berekenen
Die lijst wordt gigantisch → memorybottleneck
Een rainbow table biedt een compromis tussen beide bottlenecks.
8 kleine letters Even concreet
2·10¹¹
mogelijke wachtwoorden (26⁸)
1,46 TB
om alle hashes vooraf op te slaan
2,4 dagen
bruteforce aan 1 miljoen hashes per seconde
minuten
met een GPU aan 2,8 miljard per seconde (2011)
Puur bruteforcen of puur precomputen loont nauwelijks.
Rainbow table: het concept
Zonder rainbow table: ieder wachtwoord mapt naar exact één hash (omslachtig).
Een rainbow table is een gecomprimeerde tabel van precomputed hashes: niet alles bewaren, en toch een grote set bestrijken.
Vergelijk: de oneven getallen van 1 tot 101 bewaren als
start=1, eind=101, stap=2
Rainbow table: opbouwen
Kies een startpunt: een wachtwoord uit de set
Genereer de hash
Pas een reductiefunctie toe → terug naar een wachtwoord
Van de hash via de reductiefunctie terug naar een ander wachtwoord.
Reductiefunctie: bv. som van de ASCII-waarden → index in de set.
Rainbow table: de chain
Herhaal hash + reductie duizenden keren → een chain
Bewaar enkel het startpunt en de laatste hash
Voorbeeld van een chain.
Meerdere chains met verschillende reducties
Drie parallelle chains, elk met een eigen reductiefunctie (kleur). Bron: Wikimedia Commons, CC BY-SA 2.5.
Rainbow table: kraken
Start met de gestolen hash (waarvan we het wachtwoord willen weten)
Pas reductie + hash toe tot je een bekend eindpunt vindt (zo weet je in welke chain je zit)
Neem het startpunt van die chain
Herhaal hash + reductie tot je de gestolen hash bereikt
Eén stap terug = het wachtwoord!
Het kraken van een hash met een rainbow table.
Rainbow tables: conclusie
Een efficiënte manier om grote sets wachtwoorden te kraken
Een compromis tussen tijd en opslag
Werkt enkel bij dictionary-based wachtwoorden
Wat als identieke wachtwoorden verschillende hashes kregen? → Salting!
Stap 3 Salting
Een salt is een random extra stuk dat je vóór het hashen aan het wachtwoord toevoegt.
Het salting proces.
Unieke salt per gebruiker: identieke wachtwoorden geven andere hashes. De set wordt te groot voor rainbow tables.
Salting: de databank
Gebruikersnaam
identificatie
Salt
random waarde (minimum 32 bits)
Hash
hash van wachtwoord + salt
Zoals een IV
Net als de initialisatievector (IV) bij symmetrische encryptie: dezelfde plaintext levert verschillende ciphertexts op (zie ECB).
Pass-the-hash?
Ook nu ben je nog steeds niet beschermd tegen pass-the-hash aanvallen.
Mimikatz
Origineel een demo die aantoonde dat Microsoft-authenticatie onveilig was. Snel overgenomen door digitale stropers: vindt en hergebruikt authentication tickets op Windows.
Pass-the-hash
Windows NTLM hashes
Pass-the-ticket
Kerberos tickets
Golden Ticket
KRBTGT account: vervalt niet!
Pass-the-cache
Tickets op Mac, Unix en Linux
2017 Mimikatz en NotPetya
Mimikatz is automatiseerbaar, en dus gevaarlijk op schaal.
NotPetya: ransomware-aanval op Oekraïne
Een aangepaste Mimikatz-variant vindt hashes en tickets
Daarmee logt de ransomware in op andere systemen en verspreidt ze zich over het netwerk
Getraceerd naar Sandworm, een Russische hackinggroep onder de GRU (militaire inlichtingendienst).
Deel 3 CRAM en SCRAM
Challenge-Response Authentication Mechanism
CRAM
Je krijgt een challenge (vraag) en moet een geldig response (antwoord) geven.
Biometrics als identificatie: een aanvaller kan niet meer zeggen “ik ben persoon X” terwijl de scanner de vingerafdruk van persoon Y registreert.
Factor 3 Iets wat je hebt
Een fysiek object is moeilijk na te maken. In essentie bevat het een veel langer wachtwoord dan een mens kan onthouden.
Smartphone
Met een authenticator app (Google Authenticator, …)
USB-sleutel
YubiKey, Titan Key, …
Nadeel
Een fysiek object kan je verliezen, of het gaat stuk.
Deel 5 Federation en SSO
Zelf logindata beheren? Grote kans op fouten.
Single Sign-On (SSO)
Eénmaal inloggen → toegang tot meerdere applicaties.
Inloggen bij Google = meteen GmailYouTubeDrive …
Identity provider (IdP)
De centrale partij waaraan de authenticatie wordt uitbesteed. Bevestigt wie je bent.
Service provider
De applicatie. Vertrouwt op de bevestiging van de IdP.
Federation
SSO over de grenzen van organisaties heen: inloggen met je bestaande Google-, Facebook-, … account.
Een vereenvoudigd SSO proces.
Jouw site = service provider, Google/Facebook = identity provider. Hoe je gebruikerswachtwoorden opslaat, is dan niet langer jouw zorg.
Delegation vs federation
Delegation
Verplicht inloggen met één specifieke third-party (bv. Facebook).
Federation
Éénder welke compatibele third-party (bv. via OpenID).
Typische SSO knoppen.
OAuth (open authorization) is een gestandaardiseerde manier om aan authenticatie te doen.
Privacy
In hoeverre vertrouw je Google of Meta met jouw (login)data?
Bij federatie doet een third-party de eigenlijke authenticatie.
Deel 6 WebAuthn en passkeys
Inloggen zonder wachtwoord.
Passkeys
Een passkey combineert asymmetrische crypto met hardware authenticatie.
Met WebAuthn log je in zonder wachtwoord, via een authenticator die je bij je hebt: een USB-sleutel of je smartphone. Geen complexe wachtwoorden meer onthouden.
Termen die je zal tegenkomen
FIDO Alliance
organisatie achter de standaarden (Fast IDentity Online)
WebAuthn
Web Authentication API, laat websites met authenticators communiceren
Je identificeert je lokaal: vingerafdruk, PIN, YubiKey, …
Je toestel maakt een sleutelpaar: de private sleutel blijft, de publieke gaat naar de website
De website heeft nooit toegang tot de private sleutel. “Het wachtwoord verlaat nooit het apparaat.”
Het attestation object
De publieke sleutel gaat niet zomaar over de draad, maar zit verpakt in een attestation object:
Publieke sleutel
Die de website bewaart.
Signed challenge
De challenge van de server, als bewijs van authenticiteit.
Credential ID
Certificaat
Bewijst dat de publieke sleutel wel degelijk de jouwe is.
Synced passkeys
Verlies je je authenticator, dan ben je al je accounts kwijt.
Je private sleutels staan op de authenticator. Een password manager met synced passkeys bewaart ze veilig én synchroniseert ze naar je andere apparaten.
Inloggen met een passkey
Op basis van public key crypto:
Server stuurt een challenge
Jij encrypteert die met je private sleutel
Server decrypteert met je publieke sleutel
Lukt het? Geauthenticeerd
Het login proces met een passkey.
Deel 7 Authenticator apps en TOTP
Time-based One-Time Password
Authenticator apps
Google AuthenticatorMicrosoft AuthenticatorAuthy
30 s
en je krijgt een nieuwe code
6
cijfers per code, in te voeren naast je wachtwoord
Hoe maakt een app op jouw telefoon dezelfde code als de server verwacht? Met TOTP: Time-based One-Time Password.
TOTP: de gedeelde geheime sleutel
Bij het koppelen van je authenticator app:
De website genereert een geheime sleutel (typisch 160 bits)
Je scant de sleutel als QR-code met de app
Server en app bewaren nu dezelfde sleutel
Dit is het enige moment waarop de sleutel wordt uitgewisseld. Daarna communiceren app en server nooit meer rechtstreeks.
Waarschuwing
De QR-code bevat de volledige geheime sleutel. Geen screenshots maken! Wie de sleutel heeft, kan jouw codes genereren.
TOTP: het algoritme
Twee ingrediënten: de gedeelde sleutel en de huidige tijd.
Tijdstap
Unix-tijd (seconden sinds 1 jan 1970) ÷ 30, naar beneden afgerond
HMAC
geheime sleutel + tijdstap → een lange hash
Dynamic truncation
hash → een zescijferig getal: de code op je scherm
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": true}} }%%
graph LR
A("Geheime sleutel 🔑") --> C("HMAC")
B("Unix-tijd ÷ 30 ⏱️") --> C
C --> D("Hash")
D --> E("Truncation")
E --> F("847 293")
style F fill:#44aa44,stroke:#333,color:#fff
TOTP: waarom is het veilig?
Eenmalig
Een code is slechts 30 seconden geldig. Een onderschepte code is snel vervallen.
Offline
Na de registratie is geen internet meer nodig. Enkel de tijd synchroniseert.
Onvoorspelbaar
Zonder de geheime sleutel zijn toekomstige codes onmogelijk te berekenen.
Servers aanvaarden meestal ook de code van het vorige en volgende tijdsblok (~90 s marge), om klokverschillen op te vangen.
TOTP is niet onfeilbaar
Real-time phishing: een proxy tussen jou en de echte website.
TOTP
De proxy onderschept wachtwoord én TOTP-code tegelijk
De aanvaller kan nog steeds inloggen
Passkeys
Gebonden aan het domein van de website
Hiertegen beter beschermd
Drie gouden regels
Alles in dit hoofdstuk valt terug te brengen tot:
Client → server
Het wachtwoord gaat nooit van de client naar de server.
hashingCRAMSCRAM
Server → client
Het wachtwoord gaat nooit van de server naar de client.
wachtwoord vergeten-test
Op de server
Het wachtwoord staat er nooit in leesbare vorm.
hashing + salting
Passkeys gaan nog een stap verder: het wachtwoord (de private sleutel) verlaat zelfs de authenticator niet.
Conclusie
Authenticatie
Bewijzen wie je bent. Autorisatie = wat je mag.
Wachtwoorden
Nooit plaintext. Hashing + salting als minimum.
CRAM / SCRAM
Het wachtwoord gaat nooit over de draad. De échte SCRAM stopt ook pass-the-hash.
MFA
Weten, zijn, hebben, waar/wanneer. Meer factoren = veiliger, minder gebruiksvriendelijk.
TOTP
Gedeelde sleutel + tijd → eenmalige codes.
Passkeys
WebAuthn: asymmetrische crypto, zonder wachtwoorden.