Etik & brute force
29 försök, en mikrosekund
Caesar-chiffret du byggde i milstolpen har en svaghet. Att kalla det en svaghet är förresten snällt: en angripare som fångar ett chiffer behöver inte nyckeln. Hen kan gissa, och det finns bara 29 gissningar att göra, en förflyttning per bokstav i alfabetet. Testa alla, läs av vilken rad som blir svenska, klart. Det kallas ett Brute force En angreppsstrategi som systematiskt testar varje möjlig nyckel tills rätt hittas. Kräver ingen intelligens eller förkunskap om nyckeln, enbart beräkningskraft och tid. Effektivt när nyckelrummet är litet. -angrepp: att systematiskt testa varje möjlig nyckel tills en fungerar.
Det vi inte nämnde är hur länge det tar. Svaret är: ungefär en mikrosekund. En vanlig dator testar alla 29 skift, dekrypterar texten för varje ett och skriver ut kandidaterna innan du hunnit lyfta blicken från skärmen. Chiffret Julius Caesar litade på för att skydda militär kommunikation krossas av en handfull rader Python.
Kodknäckaren du bygger heter Brutus force, och namnet är inte slumpartat. Brutus var senatorn som förrådde och mördade Caesar. “Et tu, Brute?” lär Caesar ha sagt i sina sista ögonblick. Det känns som rätt namn på ett program som knäcker hans kryptering.
Brutus, första versionen
Kärnan är en loop över alfabetets längd som anropar din egen dekryptera() för varje skift. I sandlådan nedan har vi klistrat in en dekryptera så att du kan köra direkt, i din egen kod importerar du den i stället med from caesar import dekryptera, alfabet, precis som du lärde dig i Ditt eget bibliotek.
Lägg märke till att loopen räknar range(len(alfabet)) och inte range(29). Tjugonio är rätt svar för svenska, men det är ett svar koden inte behöver kunna i förväg. Byter någon till det engelska alfabetet fungerar brutus fortfarande, och du slipper leta efter en handskriven siffra i en fil du glömt bort.
Lägg märke till att exemplen är skrivna med gemener. Det beror på att den Caesar du byggde arbetar med det gemena alfabetet och släpper igenom allt annat, inklusive versaler, oförändrat. Skriver du in HEJ får du tillbaka HEJ. Vill du att chiffret ska hantera stora bokstäver är det den robusta versionen från nästa nivå i Caesar-milstolpen som gäller. Här håller vi oss till gemener.
Redo.
En av de 29 raderna är läsbar. Resten är brus. Ditt öga hittar den rätta på ett ögonblick, och datorn hann testa alla 29 ännu snabbare. Det är loopens hela poäng: den gör ett arbete som skulle ta dig minuter för hand, snabbare än du hinner blinka.
Hur snabbt är det egentligen?
Att det känns snabbt är en sak. Att mäta det är en annan. time-modulen En inbyggd Python-modul för tidsrelaterade operationer. time.time() returnerar aktuell tid som ett decimaltal (sekunder sedan 1 januari 1970). Differensen mellan två anrop ger exekveringstiden för ett kodblock. mäter tiden, alltså hur lång tid som faktiskt passerade. Anropa time.time() före och efter loopen, så är differensen tiden det tog:
import time
from caesar import dekryptera, alfabet
def brutus_force(chiffer):
start = time.time()
for steg in range(len(alfabet)):
print(f"Steg {steg:2}: {dekryptera(chiffer, steg)}")
tid = time.time() - start
print(f"
Klart på {tid:.6f} sekunder.") Den utskrivna tiden hamnar troligen någonstans mellan 0.0001 och 0.001 sekunder. Det är inget mätfel, det är faktiskt så lång tid det tar att bryta chiffret.
Att hitta rätt rad automatiskt
Ditt öga hittar den läsbara raden lätt. Men ett program kan göra det åt dig, om du ger det en lista med vanliga ord att leta efter:
VANLIGA_ORD = ["och", "att", "det", "en", "ett", "är", "har", "jag", "med", "som", "vad", "gör"]
def verkar_läsbar(text):
orden = text.split()
return any(ord in orden for ord in VANLIGA_ORD)
def brutus_force_smart(chiffer):
for steg in range(len(alfabet)):
försök = dekryptera(chiffer, steg)
if verkar_läsbar(försök):
print(f"* Möjlig klartext (steg {steg}): {försök}") Funktionen any() En inbyggd funktion som returnerar True om minst ett element i en itererbar uppfyller ett villkor. Kortsluter, slutar testa när en träff hittas. är ett kompakt sätt att fråga om minst ett element uppfyller ett villkor. Den slutar leta så fort den hittar en träff, och behöver inte kontrollera resten.
Nyckelrummet, varför storlek är allt
Caesars svaghet är inte en dålig algoritm i sig, det är ett löjligt litet Nyckelrum (key space) Mängden möjliga nycklar i ett kryptosystem. Caesar har 26. AES-256 har 2^256, ett tal med 77 siffror. Nyckelrummets storlek är det primära måttet på ett kryptosystems motståndskraft mot brute force. , 29 stycken. Moderna krypteringssystem bygger hela sin säkerhet på att göra nyckelrummet astronomiskt stort.
En fyrsiffrig PIN-kod har 10 000 möjliga kombinationer. En dator testar dem på millisekunder, men din bank låser kortet efter tre fel. Det är inte kryptografisk säkerhet, det är hastighetsbegränsning.
Ett lösenord på åtta tecken, valt ur de 94 tecken ett tangentbord ger, har 94⁸ ≈ 6 biljarder kombinationer. Det är knäckbart på timmar med specialiserad hårdvara. Fyra tecken till, alltså tolv i stället för åtta, ger 94¹² ≈ 475 biljoner miljarder, och då tar samma angrepp tusentals år. Fyra tecken är hela skillnaden mellan en eftermiddag och en livstid.
Det är därför lösenordskrav finns. Inte för att irritera dig, utan för att göra nyckelrummet så stort att en brute force aldrig hinner igenom det.
Tiderna ovan är storleksordningar och inte exakta löften, för de hänger på hur snabb angriparens hårdvara är och hur slarvigt lösenorden lagrats. Säkerhetsföretaget Hive Systems räknar om uträkningen varje år mot aktuell hårdvara och publicerar den som en tabell. Jämför gärna ett par årgångar. Att samma lösenord flyttar sig uppåt i tabellen år för år är hela poängen: ditt lösenord blir svagare med tiden utan att du gör någonting alls.
När nyckelrummet var för stort ändå
Din loop testade 29 nycklar. Under andra världskriget stod Alan Turing och kollegorna vid Bletchley Park inför den tyska Enigma-maskinen, ett chiffer med ett nyckelrum så stort att uttömning var otänkbar med den tidens medel. Att testa alla var uteslutet.
De knäckte det ändå, och inte genom att bli snabbare. De hittade svagheter i hur maskinen användes: meddelanden som alltid började likadant, en konstruktionsdetalj som gjorde att ingen bokstav någonsin krypterades till sig själv, slarv hos operatörer som återanvände inställningar. Varje sådan upptäckt strök enorma delar av nyckelrummet, tills det som återstod var litet nog att söka igenom med maskiner de byggde själva.
Det säger något om säkerhet som gäller än i dag. Nyckelrummets storlek är golvet, inte taket. Ett system faller sällan för att någon räknade igenom alla nycklar, det faller för att någon hittade ett sätt att slippa. Och arbetet vid Bletchley Park la på köpet grunden till den moderna datorn du sitter vid nu.
Etisk hacking, kunskap och tillstånd
Det du precis skrev är ett kryptoangrepp. Det är också exakt vad en Penetrationstestning Att på uppdrag försöka ta sig in i ett system för att hitta svagheterna innan en riktig angripare gör det. Samma tekniker som ett angrepp, men med tillstånd och med syftet att felen ska lagas. gör dagligen, alltså någon som får betalt för att försöka ta sig in i ett system. Med en avgörande skillnad: tillstånd.
Säkerhetsforskning och Etisk hacking Auktoriserad säkerhetsgranskning av ett system i syfte att hitta och rapportera sårbarheter. Utförs av certifierade penetrationstestare med skriftligt tillstånd från systemets ägare. är legitima och välbetalda yrken. Jobbet är att hitta svagheter i ett system innan en riktig angripare gör det, och rapportera dem så att de kan lagas. Google, Microsoft och nästan varje stort teknikföretag betalar ut bug bounties, pengar till vem som helst som hittar och anmäler ett säkerhetshål.
Skillnaden mellan säkerhetsforskning och dataintrång är inte tekniken. Det är tillståndet och avsikten. Samma verktyg, fundamentalt olika sammanhang.
Nästa del vänder blicken från den som angriper till den som förvaltar. Du har nu sett hur lite som krävs för att komma åt något dåligt skyddat, och det är precis den insikten som gör frågan om andras data till ditt ansvar och inte bara en juridisk formalitet.
Uppgift: Brutus i aktion
Skapa filen brutus.py i samma mapp som din caesar.py.
Importera med
from caesar import dekryptera, alfabetoch sätt ihop de två funktionerna från lektionen:brutus_force(chiffer)som testar alla skift och mäter tiden, ochbrutus_force_smart(chiffer)som flaggar troliga klartexter medany()och en ordlista.Nu det som inte står i lektionen: kryptera tre olika meningar med tre olika nycklar, kör knäckaren på alla tre och kontrollera att den hittar rätt klartext varje gång. Fungerar det inte, är det din ordlista som är för tunn. Utöka den tills det fungerar, och skriv en rad om vilka ord du behövde lägga till.
Pusha med commit-meddelandet
"Brutus force: Caesar-chiffret knäckt".
Vad händer om
Kryptera ett enda kort ord, till exempel hej, och kör brutus_force_smart() på det. Flaggas rätt rad, blir det tyst, eller flaggas flera? Jämför med hur säker du kände dig när texten var en hel mening, och förklara vad det är detektionen tappar när texten krymper.
Motivera & reflektera
Du fångar ett chiffer och vet att det är Caesar-krypterat på svenska. Brutus force ger dig tre rader som alla ser läsbara ut. Beskriv hur du avgör vilken av de tre som är den äkta klartexten, utan att skriva en enda rad till kod. Motivera sedan, med det som utgångspunkt, skillnaden mellan säkerhetsforskning och dataintrång: om tekniken är exakt densamma, vad är det egentligen som skiljer dem åt?
Nästa nivå
Knäck en kod som inte är Caesar. Samma metod fungerar på vilket litet nyckelrum som helst. En fyrsiffrig PIN-kod har 10 000 möjligheter, och i texten ovan påstods att en dator går igenom dem på millisekunder. Kontrollera det själv.
Skapa pinknackare.py med en funktion knäck_pin(hemlig_kod) som testar varje kod från 0 till 9999 tills den hittar rätt, räknar antalet försök och mäter tiden.
Kör den sedan med koderna 0000, 5000 och 9999 och anteckna försök och tid för varje. Varför skiljer sig tiderna åt, trots att nyckelrummet är exakt lika stort i alla tre fallen? Ändra till sist till en sexsiffrig kod, alltså en miljon möjligheter, och mät om. Hur många gånger längre tog det, och stämmer det med hur mycket nyckelrummet växte?
Tre saker att tänka på om du kör fast. Loopa med for kod in range(10000) och jämför kod direkt mot den hemliga koden som ett heltal, då slipper du bry dig om inledande nollor. Starta klockan före loopen och stoppa den när du hittat rätt, inte efter hela loopen. Och glöm inte break, annars räknar den vidare långt efter att koden är knäckt och förstör din mätning.
När du är klar: din bank låser kortet efter tre felaktiga försök, medan din pinknäckare behövde tusentals. Vad är det egentligen som skyddar kortet, nyckelrummets storlek eller spärren?