Obligatorisk oppgave 3 INF-2310 < Sikkerhet i distribuerte systemer > 18. november 2003 Obs! Denne rapporten forutsetter kjennskap til vedlagte JavaDoc informasjon samt oblig2. Tor-Eirik Bakke Lunde torebl@stud.cs.uit.no
Problemstilling: Implementere verktøy for utveksling av nøkler, det vil si utvikle programrutiner for å registrere og hente nøkler fra en allerede utviklet nøkkel-tjener basert på en veldefinert protokoll. Denne protokollen er gjengitt i detalj videre i oppgaven. Det skal også utvikles funksjonalitet for å hente ned et personalisert dokument fra en allerede utviklet dokumenttjener. Nøkkel, - og dokumenttjener var stilt til rådighet for oppgaven og implementasjonen av disse er da ikke tilgjengelig. Den generelle problemstillingen blir derfor å utvikle klientprogramvare til disse tjenerne basert på vår tolkning av protokollen og prøve å få denne tilstrekkelig opp mot den implementert på tjenersiden. Angrepsvinkel: Med basis i at de definerte protokollene er på det meste enkle utvidelse av den funksjonaliteten som ble utviklet som besvarelse på obligatorisk oppgave 1 og 2. Klasser for å håndtere sertifikater er stilt til rådighet og det eneste som da mangler i hensyn til klienten er selve implementasjonen. Løsningsmetode: Har delt inn klienten i to distinkte klienter, der den ene tar seg av utveksling av sertifikater (innbefatter offentlige nøkler, derav i praksis - nøkkeltjener) og den andre tar for seg protokollen for utveksling av dokumentet. Disse to klientene trenger mye av den samme funksjonaliteten for utveksling av data og oppkobling til tjeneren, og disse delene er da flyttet over til kode som er delt mellom dem. Ettersom det mest trolig ikke er nødvendig å opprettholde en konstant oppkobling til de forskjellige tjenerne kobles tilkoblingen fra etter bruk. Med mest trolig hentydes det her at utveksling av nøkler/ dokument i de fleste tilfellene utføres kun en gang per sesjon, og tjenerne er ikke tjent med å til enhver tid være nedlesset av tilkoblinger fra klienter. Implementasjon: Oppretter en ny klasse med navn GenericFetcher som kommer til å opptre som en superklasse til klassene DocumentFetcher og KeyFetcher som henholdsvis er ansvarlig for utveksling av dokumenter og utveksling av nøkler. GenericFetcher inneholder felles funksjonalitet for oppkobling til tjener, og gjør dette ved å bruke funksjonalitet i klassen SecureProtocol som ble utviklet som besvarelse på obligatorisk oppgave 2. For detaljer angående denne klassen, se UML diagram 1. De to nevnte underklassene er konstruert på en slik måte at de kan kjøre som frittstående program for å teste funksjonaliteten i dem, og generelt sett utgjør de klientprogrammene som er krevd som en del av oppgaven. En annen faktor under implementasjonen var at nevnte funksjonalitet skulle kunne brukes direkte fra annen kode, noe som da klientimplementasjonen DocumentFetcher benytter seg for å skaffe til veies en nøkkel som kreves for kommunikasjon med dokumenttjeneren. UML diagram 1: GenericFetcher
KeyFetcher : Følger protokollen, og det første som foretas er å koble seg opp mot nøkkeltjeneren. Dette gjøres ved å bruke funksjonalitet for dette implementert i GenericFetcher. Protokollen nevner på dette punktet to operasjoner som da kan foretas mot nøkkeltjeneren: Registrere egen personlig offentlige nøkkel: Denne operasjonen er ifølge protokollen definert til å ha en struktur som følgende: 1.1 A à B : {A, K A } KA -1 1.2 B à A : 200 OK A : Klientens identifikator B : Tjenerens identifikator K A : As offentlige nøkkel {} KA-1 : Signert ved bruk av As private nøkkel Implementasjonsmessig foregår dette på en måte der A enten genererer eller laster inn sitt UML diagram 2: KeyFetcher offentlige/private nøkkelpar fra disk og benytter dette til å opprette et objekt av klassen KeyCertificate som var stilt til rådighet av oppgaven. Det genererte sertifikatet knytter nå As identifikator til As offentlige nøkkel, og hvorvidt sammenhengen mellom dem kan verifiseres gjøres ved hjelp av signaturen som er en del av sertifikatet. Et kall funksjonen tomessage( ) i sertifikatsklassen returnerer et objekt av klassen Message som tilfredsstiller protokoll-linje 1.1. For transport av denne dataen (sertifikatet) brukes funksjonalitet ifra klassen ProtocolBase, eller da mer nøyaktig funksjonen sendmessage( ). For å ta imot svaret (protokoll-linke 1.2) benyttes en annen funksjon i samme klasse, receivemessage( ). Svaret undersøkes og dersom svaret besto av teksten 200 OK var funksjonen en suksess, andre returverdier skrives til konsoll (kun dersom debug-modus er skrudd på) og funksjonen returnerer at den operasjonen feilet. Gjøre oppslag på offentlige nøkler: Denne operasjonen er ifølge protokollen definert til å ha en struktur som følgende: 2.1 A à B : GETKEYBYNAME, P 2.2 B à A : {P, K A } KP -1 A : Klientens identifikator B : Tjenerens identifikator P : Ps identifikator K A : As offentlige nøkkel {} KP-1 : Signert ved bruk av As private nøkkel Det som skjer her er at A gjør et oppslag hos B for å finne Ps offentlige nøkkel, og utføres da ved at A da gjør ett oppslag på Ps identifikator. Implementasjonsmessig er dette knapt
verdt å kommentere, sett bort fra at strukturen på beskjeden da består denne består av to ledd der det ene inneholder teksten GETKEYBYNAME og det andre Ps identifikator. Som klartekst sendes dette da ved hjelp av sendmessage( ). Tar imot svaret ved bruk av metoden receivemessage( ) og svaret kan tolkes veldig enkelt: dersom svarbeskjeden har fire ledd rekonstrueres ett sertifikat ved hjelp av disse dataene og hvis ikke har vi mottatt en feilmelding som skal skrives til konsoll (kun dersom debug-modus er på). Før sertifikatet som ble hentet returneres til hoverprogrammet verifiseres sertifikatet ved hjelp av signaturen. Per definisjon, retrievecertificate(...), returneres ett sertifikat som svar på forespørsel dersom og kun dersom ett sertifikat ble funnet og sertifikatetets signatur ble verifisert. DocumentFetcher : Protokollen definer følgende for innlogging, henting av personalisert dokument på dokumenttjeneren: 3.1 A à P : A, P 3.2 P à A : P, A, {{P, A, I, T P, X P } KP-1 } KA} 3.3 A à P : A, P, {{A, P, K, T A, H(X P )} KA-1 } KP} 3.4 P à A : 200 OK A : P : Klientens identifikator Ps identifikator (dokumenttjener) Detaljer angående protokoll-linjer 3.2 og 3.3 er dekt i rapport for obligatorisk innlevering 2, og håndteres fullt ut av denne delen og håndteres ikke direkte i DocumentFetcher. Implementasjonsmessig håndteres dette veldig enkelt. Protokoll-linje 3.1 som innleder protokollen settes sammen og sendes med funksjonen sendmessage ( ). Dette resulterer i at dokumenttjener svarer med å sende en kryptert melding i henhold til protokollen etablert i obligatorisk innlevering 2. Klienten kaller funksjonen receivemessage( ) og mottar svaret, dekrypterer med UML diagram 3: DocumentFetcher funksjonen decodemessage( ). Protokoll-linje 3.3 definerer at forrige mottatte melding skal signeres for og dette løses med ett enkelt kall til s_sendreciept( ). Protokoll-linje 3.4 avslutter protokollen. Sikkerhetsmessig fungerer dette rimelig bra, så lenge som begge parter verifiserer den informasjonen de har mottatt, og prøver å ikke gi for mye informasjon utover det mest nødvendige. Problemet her er at ett uønsket element, kaller personen mr. X, kan skaffe til veie en del informasjon med basis i noen få kjente identifikatorer. Nevnte informasjon vil da være ciphertekst som den da automatisk mottar ved å identifisere seg ved bruk av andres identifikatorer identifikatorer som blir sendt i klartekst over nettverket i tillegg til i den definerte protokollen er disse identifikatorene lett å gjette seg fram til. Når det gjelder kryptering gjelder dette da kun den indre meldingen, og hvis mr. X selv har tilgang ett dokument kan han studere den indre strukturen i meldingene og observere strukturen
på dataen som er i den. Lete etter gjenkjennbare trekk i datastrukturen og deretter kjøre en bruteforce sjekk etter IDEA nøkkelen og håpe på at kombinasjonen treffes raskt. Dette ettersom kombinasjonene med rimelig prosesseringskraft vil til sammen utgjøre ett tidsforbruk som nesten utelukkende er lengre enn den originale dataens gyldighet. Selv om dette ikke er ett problem nå kan dette være ett poeng i morgen ettersom prosesseringskrefter radig øker til hastigheter opp mot naturlovene. Likevel bør det nevnes å kalles dårlig planlegging å legge data fritt åpent, til tross for at de er krypterte. Forrige avsnitt omtaler noe som kanskje burde vært tenkt litt over, og det er at dokumenttjeneren deler ut krypterte data i fleng uten at det blir foretatt noen som helst form for autentisering av brukeren. Protokoll-linje 3.1 identifiserer senderen, men som nevnt er denne identifiseringen ikke enstydig med autentisering. Evaluering: Kjører en test mot nøkkeltjeneren: IP: 129.242.16.149 Port: 9000 Identifikator: Testtjener Oblig-3, INF-2310, 2003h KeyFetcher programmet registrerer først mitt eget sertifikat lest inn fra filen tor.private, og henter ned sertifikatet for brukeren med identifikator oppgitt ovenfor. Dette ga følgende utskrift: Register certificate... Success Fetching certificate... Success Kjører en test mot dokumentjeneren: IP: 129.242.16.149 Port: 9001 Identifikator: Testtjener Oblig-3, INF-2310, 2003h DocumentFetcher programmet starter med å bruke funksjonalitet fra KeyFetcher til å skaffe tjenerens offentlige nøkkel som kreves for den krypterte overføringen. Programmet henter så ned dokumentet og lagrer det som filen out.txt. Selve kjøringen ga følgende utskrift: Document end: 447 Wrong timestamp (received message sent before previous message) Document written to disk *** Program finished Innhold i filen out.txt : 2003-11-16_00:33:11Test-X fra Testtjener Oblig-3, INF-2310, 2003h til Tor-Eirik Bakke Lunde <torebl@stud.cs.uit.no>: