En nonce är ett unikt värde som en enhet väljer i ett protokoll, och det används för att skydda enheten mot attacker som faller under det mycket stora paraplyet "replay".
Tänk till exempel på ett lösenordsbaserat autentiseringsprotokoll som går så här:
- servern skickar en "utmaning" (ett förmodligen slumpmässigt värde c ) till klient
- klient ska svara genom att skicka h (c || p) där h är en säker hash-funktion (t.ex. SHA-256), p är användarlösenordet och ' || ' betecknar sammankoppling
- servern letar upp lösenordet i sin egen databas, beräknar om förväntat klientsvar och ser om det matchar vad klienten skickade
Lösenord är hemliga värden som passar i mänskliga hjärnor; som sådan kan de inte vara särskilt komplexa, och det är möjligt att bygga en stor ordbok som kommer att innehålla användarlösenordet med stor sannolikhet. Med "stort" menar jag "kan räknas upp med ett medelstort kluster om några veckor". För den aktuella diskussionen accepterar vi att en angripare kommer att kunna bryta ett enda lösenord genom att spendera några veckors beräkning. detta är den säkerhetsnivå som vi vill uppnå.
Föreställ dig en passiv angripare: angriparen avlyssnar men ändrar inte meddelandena. Han ser c och h (c || p) , så att han kan använda sitt kluster för att räkna upp potentiella lösenord tills en matchning hittas. Detta kommer att bli dyrt för honom. Om angriparen vill attackera två lösenord måste han göra jobbet två gånger . Angriparen vill att ska ha lite kostnadsdelning mellan de två attackinstanserna, med hjälp av förberäknade tabeller ("regnbågstabeller" är bara en typ av förberäknad tabell med optimerad lagring; men att bygga ett regnbågsbord kräver fortfarande att räkna upp hela ordlistan och hash varje lösenord). Den slumpmässiga utmaningen besegrar dock angriparen: eftersom varje instans innebär en ny utmaning kommer hashfunktionsingången att vara annorlunda för varje session, även om samma lösenord används. Således kan angriparen inte bygga användbara förberäknade tabeller, särskilt regnbågsbord.
Antag nu att angriparen blir aktiv. Istället för att helt enkelt följa meddelandena kommer han aktivt att ändra meddelanden, släppa några, duplicera andra eller infoga egna meddelanden. Angriparen kan nu fånga upp ett anslutningsförsök från klienten. Angriparen väljer och skickar sin egen utmaning ( c ') och väntar på klientsvaret ( h (c' || p) ). Observera att den sanna servern inte kontaktas; angriparen tappar bara anslutningen plötsligt omedelbart efter klientsvaret för att simulera ett godartat nätverksfel. I den här attackmodellen har angriparen gjort en stor förbättring: han har fortfarande en utmaning c ' och motsvarande svar, men utmaningen är ett värde som angriparen har valt efter eget tycke. Vad angriparen kommer att göra är att alltid servera samma utmaning c '. Genom att använda samma utmaning varje gång kan angriparen utföra förberäkningar: han kan bygga förberäknade tabeller (dvs. regnbågsbord) som använder den speciella "utmaningen". Nu kan angriparen angripa flera olika lösenord utan att ådra sig ordbokens uppräkningskostnad för var och en. Protokollet blir:
- servern skickar en slumpmässig utmaning c
- klienten väljer en nonce n (ska vara distinkt varje gång)
- klienten skickar n || h (c || n || p)
- servern beräknar om h (c || n || p) (med p från sin databas) och ser om detta värde matchar det som klienten skickade
Eftersom klienten innehåller ett nytt slumpmässigt värde ("nonce") i hashfunktionsingången för varje session, hashfunktionsinmatningen kommer att vara tydlig varje gång, även om angriparen kan välja utmaningen. Detta besegrar förberäknade (regnbågs) tabeller och återställer vår avsedda säkerhetsnivå.
En grov emulering av en unik nonce är användarnamnet. Två distinkta användare inom samma system har olika namn. Användaren behåller dock sitt namn när han byter lösenord. och två distinkta användare kan ha samma namn på två distinkta system (t.ex. varje Unix-liknande system har en "root" -användare). Så användarnamnet är inte en bra nonce (men det är ändå bättre än att inte ha någon client nonce alls).
Sammanfattningsvis handlar client nonce om att skydda klienten från en omspelningsattack (" server "som i själva verket är en angripare, som skickar samma utmaning till varje klient som han vill attackera). Detta behövs inte om utmaningen körs över en kanal som inkluderar stark serverautentisering (t.ex. SSL). Password Authenticated Key Exchange är avancerade protokoll som säkerställer ömsesidig lösenordsbaserad autentisering mellan klient och server, utan att behöva lite förhandsförtroende ("rotcertifikaten" när en SSL-klient autentiserar SSL-servercertifikatet) och skyddar mot aktiva och passiva angripare (inklusive "cluster-for-two-weeks" attack på ett enda lösenord, så det är strikt bättre än protokollet ovan, nonce eller no nonce).