PHP krypto 5 - Digitale certifikater

Tags:    php sikkerhed krypto x509 certifikater
Skrevet af Bruger #2695 @ 07.05.2012

Introduktion


Denne femte artikel behandler nogle problemer, som vi introducerede med de asymmetriske krypterings algoritmer. Det bliver lidt teoretisk, men hæng på...jeg holder mig til de mest nødvendige funktioner.

I tredje artikel så vi på asymmetrisk kryptografi og på, hvordan det løste problemet med nøgleudveksling. Alice og Bob kan udveksle krypteringsnøgler, og selvom Eve lytter med, så kan hun ikke deltage i kommunikationen.

Men det er et meget urealistisk eksempel. Normalt vil Alice og Bob ikke kunne kommunikere så direkte ansigt til ansigt.

Alice og Bob kunne arbejde på hver deres side af jordkloden, men hvordan udveksler de så nøgler ?
Her kommer den uærlige postmand Mallory ind i billedet:

1) Bob og Alice vil kommunikere hemmeligt.
2) Bob give Mallory sin offentlige nøgle og beder ham om at levere den videre til Alice
3) Mallory tager over til Alice, men giver hende istedet sin egen offentlige nøgle
4) Alice krypterer en tilfældig hemmelig nøgle med, hvad hun tror er Bobs offentlige nøgle og giver den til Mallory
5) Mallory dekrypterer nøglen og rekrypterer den med Bobs nøgle
6) Mallory tager over til Bob og giver ham den nøgle, som er krypteret med hans offentlige nøgle
7) Alice og Bob kommunikerer nu ved hjælp af en delt nøgle, men Mallory kender den også

Dette kaldes et Man In The Middle (MITM) angreb, og er meget nemt at udføre under de rette omstændigheder.

I den virkelige verden vil Mallory nok være en router, som en hacker har overtaget, eller som administreres af en mindre pålidelig system administrator hos en internet udbyder.

Selv hvis Alice og Bob kunne mødes ansigt til ansigt, så kender de måske ikke hinanden. Hvis I møder en tilfældig person på gaden, som hævder, at han er mig, hvilken garanti har I så for, at det faktisk ér mig ?

Hvis han hiver et pas frem, så har I en rimelig sikkerhed. Et pas er svært at forfalskne, og det er udstedt af en myndighed, som vi bør kunne stole på. Vi kan bruge noget lignende i krypto verdenen.

Mød Trent


Trent er endnu en fiktiv person i historierne om kryptografi, og han er en myndighedsperson, som alle kender og stoler på, og alle har hans offentlige nøgle tatoveret på brystet. Nu sker følgende:

1) Alice og Bob vil kommunikere hemmeligt
2) Bob går til Trent og beder ham om at attestere, at hans nøgle faktisk tilhører ham
3) Trent tjekker Bob på kryds og tværs og signerer Bobs offentlige nøgle sammen med et dokument med Bobs identitet (navn, e-mail, osv.) og giver dette til Bob
4) Bob giver denne signatur og andre data til Mallory og beder ham om at levere det til Alice
5) Mallory leverer dataene til Alice
6) Alice tjekker, at signaturen faktisk tilhører Trent og at dataene matcher Trents signatur
7) Alice genererer en tilfældig nøgle som krypteres med Bobs offentlige nøgle og giver den til Mallory
8) Mallory leverer nøglen til Bob
9) Bob dekrypterer og kommunikerer nu med Alice

Mallory kan ikke længere substituere Bobs nøgle med sin egen, for Mallorys nøgle er ikke signeret af Trent, og selv hvis den var, så var Bobs identitet ikke signeret sammen med Mallorys nøgle. Det ville Trent aldrig gøre.

Certifikater


Der er to ting at bide mærke i i ovenstående historie, og den ene er, at vi skal binde vores identitet sammen med vores nøgle. Den anden er, at vi skal have vores identitet og nøgle signeret af en person, som alle kender og stoler på. Resultatet er et certifikat. Et certifikat er et dokument, som indeholder informationer om en person eller en server samt dennes offentlige nøgle. Certifikatet er derudover signeret af en autoritet, som har ansvaret for at verificere, at personen er den, som han siger (eller at serveren tilhører organisationen, som certifikatet udstedes til).

Første skridt er at sammenkæde vores identitet og offentlige nøgle i, hvad der kaldes et "certificate signing request" (herefter kaldet CSR). Det kan vi gøre med følgende script:
Fold kodeboks ind/udPHP kode 


Nu sagde jeg tidligere, at det var vores offentlige nøgle, som skulle bruges i certifikatet, men hvorfor bruger vi så den private nøgle ?

Den offentlige nøgle kan udledes fra den private, og udover vores informationer og offentlige nøgle, så skal hele skidtet signeres med vores private nøgle. Den private nøgle bliver ikke lagt ind i certifikatet.

'$dn' arrayet indeholder vores oplysninger, og disse kaldes samlet set for et "distinguished name".

Vi prøver:
Fold kodeboks ind/udKode 


Nu har vi halvdelen af certifikatet, så nu mangler vi bare én, som kan signere det. Vi mangler Trent!

Certificate Authority


I den virkelige verden varetages rollen som Trent af såkaldte Certificate Authorities (herefter kaldet CAs).

Et CA er et firma eller organisation, som har retten til at signere CSRer og dermed udstede fuldgyldige certifikater. De skal til gengæld gøre alt hvad de kan, for at verificere, at den, som de udsteder certifikater til har retten til certifikatet.

Derudover bliver de et yndet hackermål, for hvis man kan få fat på et CAs private nøgle, så kan man udstede sine egne certifikater, som alle vil stole på, og man kan dermed udgive sig for at være hvem som helst...f.eks. Microsofts Update server.

Vi har alle CAs certifikater på vores maskiner (ikke tatoveret på brystet, men tæt på). På min Ubuntu server ligger de i '/etc/ssl/certs', men det er heller ikke unormalt, at certifikaterne er compilet ind i softwaren, som skal bruge dem.

Når vi skal tjekke, om et modtaget certifikat er signeret af én vi stoler på, så skal vi altså bare tjekke, om signaturen matcher én af de mange certifikater, som vi allerede har liggende.

Men nu gider vi ikke i denne artikel at gå ud og betale for at få udstedt et certifikat. Det er også en lang og bureaukratisk proces, men vi kan gøre noget andet. Vi kan signere certifikatet selv.

Self signed certificate


Hvad betyder det, at vi selv signerer vores certifikat ?

Det betyder, at jeg står inde for, at jeg er mig. Det er temmelig usikkert, men det kan bruges til to ting, nemlig testing og til at opbygge sin egen CA.

Hvis certifikaterne under '/etc/ssl/certs' er ægte certifikater, hvem er de så signeret af ?

De er ALLE self signed certificates, men nogen har gået igennem ild og vand for at sikre at de alligevel er ægte. Det må vi stole på. Vi kan selv signere vores eget certifikat, men vi kan nok ikke få det distribueret til hele verden, men det er måske heller ikke nødvendigt.

Koncekvensen, af at signere selv, er, at standard software pakker som f.eks. web browsere vil komme med en advarsel, hvis den støder på det, og derfor bør man ikke bruge self signed certificates på sit offentligt tilgængelige website, men det kan bruges lokalt til at teste med.

Derudover kan man opbygge sin egen CA til et mindre lukket netværk. Hvis man f.eks. har et VPN, hvor kun få udvalgte skal have adgang, så kan man give dem et self signed certificate som har signeret serverns certifikat, og så kan det være godt nok.

Men vi skal altså have et script, som kan bruges til at signere et CSR med et certifikat. Det kan vi med følgende:
Fold kodeboks ind/udPHP kode 


Det endelige certifikat får en udløbsdato, som vi specificerer som det antal dage, fra dags dato, som certifikatet skal være gyldigt.

Specificerer vi et eksisterende certifikat som femte argument til scriptet, så bruges det til at signere med. Undlades det, laver vi et self signed certificate, som kan bruges til testing eller som CA i et lukket system.

OpenSSL bruger en konfigurationsfil til at udfylde visse dele af certifikatet. På min Ubuntu maskine er denne konfigurations fil /etc/ssl/openssl.cnf. Pr. default når man signerer et certifikat, så får man et CA certifikat, og det ønsker vi ikke, at alle har. Kun hvis vi laver et self signed certificate, så hvis der specificeres et certifikat til at signere med, så overrider vi hvilke X509 udviddelser, der skal bruges, i vores tilfælde 'usr_cert'. Denne skal være i konfigurationsfilen, og hvis ikke den er det, så virker det ikke. Kig i din konfigurationsfil, hvis ovenstående ikke virker, eller lad være med at override. Konfigurationsfilen er meget fleksibel, og vi kan bruge den til mange ting, også styre nøjagtigt, hvad certifikatet må bruges til (SSL server, SSL klient, signering af mails, etc.), men det er lidt mere avanceret, så det må du selv lige læse op på, hvis det er nødvendigt.

Vi prøver det:
Fold kodeboks ind/udKode 


Vi kan nu slette vores CSR, det skal ikke bruges længere.

Lad os lave et script, som kan fortælle lidt om, hvad et certifikat indeholder:
Fold kodeboks ind/udPHP kode 


Vi prøver det af på vores nye certifikat:
Fold kodeboks ind/udKode 


Vi kan se, at Issuer og Subject er éns, og det betyder, at det er et self signed certificate. Vi kan nu bruge vores certifikat til f.eks. at enable SSL i vores web server.

Det gør vi med følgende Apache konfiguration:
Fold kodeboks ind/udKode 


Yderligere kan vi se under "X509v3 Basic Constraints" at det er et CA certifikat, hvilket betyder, at vi kan bruge certifikatet til at signere andre certifikater.

Prøv evt. at se indholdet af en af CA certifikaterne i '/etc/ssl/certs'.

Lad os se, om vi kan signere en andens CSR:
Fold kodeboks ind/udKode 


Super. Issuer og Subject er ikke den samme og Poul har ikke 'CA:TRUE'.

Validering


Godt så. Nu har vi muligheden for at generere certifikater, men vi skal også kunne tjekke, om et certifikat er validt.

Det kan man ikke som sådan, men man kan tjekke, om certifikatet er validt til et specifikt formål. At udstede certifikater til specifikke formål er lidt avanceret, så det dækker jeg ikke, men vi kan tjekke, om det er validt til et hvilket som helst formål, og det kan vi med følgende kode:
Fold kodeboks ind/udPHP kode 


Vi prøver det af:
Fold kodeboks ind/udKode 


Det virker !!

Men kan Poul signere certifikater ? Lad os prøve.
Fold kodeboks ind/udKode 


Poul kan altså godt signere, men validitetstjekket fejler fordi Pouls certifikat ikke har 'CA:TRUE'.

Web of Trust


Det, vi indtil nu har dækket, er en del af PKI (Public Key Infrastructure) og kaldes chain of trust. Man kan kæde certifikater sammen så vores CA certifikat signere Pouls certifikat med tilladelse til at signere. Poul signerer så Peters, som signerer Karins, som signerer Oskars. Hvis alle i kæden har tilladelse til at signere, så stoler vi på Oskars certifikat.

Programmerne PGP og GPG og et par andre bruger noget andet, nemlig Web of Trust. Her er der ikke ét rod certifikat som alle stoler på. Istedet har alle mulighed for at signere alle andres nøgler, og man kan godt have mange til at signere den samme nøgle.

Modtager du en nøgle fra en fremmed (lad os kalde ham Poul), hvordan ved du så, at det faktisk ér Poul ?
Du kigger på, hvem der har signeret hans nøgle. Måske har din bedste ven Peter signeret den, og så er der da noget, der tyder på, at den er god nok, for vi stoler på Peter.

Til visse OpenSource sammenkomster vil der endda være arrangeret såkaldte "key signing parties", som ikke handler om druk, men om at tjekke hinandens oplysninger og signere hinandens GPG nøgler.

OpenSSL har ikke noget, som kan håndtere dette, men det kunne man jo selv implementere.

Afslutning


Nu ved vi alt om digitale certifikater....eller rettere, vi har lige nøjagtigt skrabet overfladen. Det er et stort emne, men vi har sandsynligvis ikke behov for meget mere. Vi kan nu udveksle nøgler og være rimelig sikre på, at de tilhører, hvem vi tror, de gør.

Der ér problemer med digitale certifikater. Mange steder "stoler" vi på folk. Vi stoler på, at CAerne gør sit arbejde med at baggrundstjekke, men det er ikke altid de gør det, og der er mange CAer. Bare én fejler, så er der et problem. Og hvis bare én CA mister sin nøgle, så er der et problem.

Dan Kaminsky, kendt for "hullet" i DNS, opridser her en hel del af problemerne: www.youtube.com/watch?v=AG8XZto7APo
Den er værd at se.

Hvad skal vi se på i næste artikel ?
Det ved jeg ikke endnu, men jeg finder nok på noget. Till then.


Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (0)

Du skal være logget ind for at skrive en kommentar.
t