Over cryptografie en het maken van sleutels en certificaten met SSL (voor beginners) zijn veel sites geschreven. Echter, niet zoveel in het Nederlands. En dat is soms best handig. Deze site behandeld niet het hoe en waarom van cryptografie. We gaan er van uit dat dat al een beetje bekend is. Dus als je nog niet weet van een sleutel of een certificaat is, zit je hier niet goed, kijk onder bij de links. Deze site behandelt:
We doen dit alles met openssl , dus we gaan er van uit dat je dit werkend op je machine hebt geinstalleerd. (Je hebt niets anders nodig) De commando's zijn in te voeren onder linux, of cygwin onder windows. OpenSSL werkt ook direct onder windows, maar de ander commando's zullen moeten worden aangepast (zoals more, mkdir etc.)
Nog een laatste opmerking, het is de bedoeling dat je deze stappen op je eigen bak zelf uitvoert, en daarom is de output van de commando's weggelaten.
OK, hier gaan we het stap voor stap doen, we willen werken in een aparte directory, dus:
> mkdir ssl > cd sslMaak een sleutel:
> openssl genrsa -des3 -out server.key 1024Hiermee genereren we een key die meteen beveiligd wordt met een blockcipher, hier triple des (probeer ook aes256) voor rijndahl beveiliging. OK we hebben nu een server.key, dit is een private key voor de server. Die ziet er zo uit
> more server.keyNu kunnen we ook even bekijken hoe die key eruit ziet, maw wat staat erin:
> openssl rsa -noout -text -in server.keyJe kunt nu ook naar de echte (unencrypted) versie van de secret key kijken
> openssl rsa -in server.key
Nu willen een certificeringsverzoek opstellen. Hiertoe moeten we een aantal vragen beantwoorden, die in dit verzoek worden opgenomen, en dan worden ondertekend door de autoriteit, die natuurlijk wel zou moeten controleren of dit allemaal juist is. We gaan er in dit voorbeeld vanuit dat je kiest van "Jan BV" als aanvrager.
> openssl req -new -key server.key -out server.csrDit genereert een server.csr file waarin deze zaken zijn opgenomen. Kijk maar eens even:
> openssl req -noout -text -in server.csrTot hier is het het stuk dat je altijd zelf kunt.
Als je een certificaat wilt dat direct door browsers wordt herkent, kun je dit document, samen met geld, sturen naar Verisign, Thawte (zelfde bedrijf) etc etc. Er zijn ook goedkopere, zoals ssl.nu, of sslcertificaten.nl. We kunnen echter ook zelf CA worden Certifying Authority (CA) worden. Dat gaan we nu behandelen.
Daarvoor moeten we weer een nieuwe private key aanmaken
> openssl genrsa -des3 -out ca.key 1024Maak nu een Zelf - ondertekend CA Certificate (X509 structure) met de RSA key van de CA (in PEM formaat) (gebruik Piet NV als issuer):
> openssl req -new -x509 -days 365 -key ca.key -out ca.crtEn ff kijken of dit gelukt is:
> openssl x509 -noout -text -in ca.crtEen (MD5) fingerprint van het certificate kan altijd worden opgevraagd met
> openssl x509 -fingerprint -noout -in ca.crt
Nu moeten we ons oorspronkelijke certificate gaan ondertekenen met die van de CA.
> openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crtDit levert een server certificaat af: server.crt Laten we nu eens aan de binnenkant kijken:
> openssl x509 -noout -text -in server.crtOK, we zien een certificaat uitgegeven door Piet NV en van Jan BV. Daarmee zegt Piet NV dat de info van Jan BV echt is.
Er zijn verschillende formaten, waarin de certificaten kunnen zijn uitgevoerd. Je hebt het PEM en DER formaten voor het certificaat. De bovenstaande formaten zijn in PEM. Converteren naar DER gaat zo:
> openssl x509 -in test.crt -out test.der -outform DERen zo ga je terug
> openssl x509 -in test.der -inform DER -out test.pem -outform PEMtest.pem en test.crt zijn identiek:
> md5sum test.crt > md5sum test.pemEen DER vorm kan je niet gemakkelijk op het scherm bekijken. Daarnaast heb je ook nog PKCS12 (en voorgangers ...) die je kunt converteren. " In general, the PEM formats are mostly used in the Unix world, PKCS12 in the Microsoft world and DER in the Java world. "
omzetten van pem certificate naar pkcs12 gaat als volgt
> openssl pkcs12 -export -out usercert.p12 -inkey user.key -in user.crten terug (mbv twee commando's)
> openssl pkcs12 -clcerts -nokeys -in usercert.p12 -out usercert.pem > openssl pkcs12 -nocerts -in usercert.p12 -out userkey.pem
We hebben, als we een key opvragen, de volgende onderdelen:
p,q
n=pq
E
zdd ( E<p.q ) & ( ggd(E,(p-1)(q-1))=1 )maw
E
en (p-1)(q-1)
zijn relatief priem (bezitten geen
gemeenschappelijke factoren). Omdat (p-1)(q-1)
even is,
is E
dus altijd oneven (waarom?).
De E
heet de publieke exponentD
van E
, dus
bepaal D
zdd DE mod (p-1)(q-1)=1of te wel
DE-1
is deelbaar door (p-1)(q-1)
X
die voldoet aanD=(X(p-1)(q-1)+1)/EAls je
X
laat oplopen komt je vanzelf een deelbare
breuk tegen. Dat duurt eindig want natuurlijk geldt
D<pd
. De D
heet de private exponent. G=B^E mod pq , met B<pqwaarbij
B
je boodschap is en G
de geheime boodschap,
Encrypten mag iedereen, dus je publieke sleutel is
(E, pq)
B=G^D mod pqnatuurlijk is
G<pq
.
Decrypten mag je alleen zelf, je privesleutel is
(D,pq)
exponent1 = D mod (p-1) exponent2 = D mod (q-1) coefficient = (inv q) mod pEn dienen alleen om de decryptie gemakkelijker te maken. (bij encryptie mag je die helemaal niet weten)
Het leuke is dat dit een symmetrisch proces is. Als iemand mij een bericht wil sturen, dat gebruikt hij de public key om het de coderen, en ik mijn private key om het te decoderen. Als ik iemand een bericht wil sturen en ik wil de ontvanger ervan overtuigen dat het bericht van mij komt, dan maak ik van mijn bericht een hash die ik met mijn privesleutel codeer. De ontvanger kan vervolgens deze gecodeerde hash met de publieke sleutel decoderen (dat kan iedereen) zelf de hash bepalen en vaststellen dat deze identiek zijn.
Laten we een voorbeeld nemen, Stel je wilt bytes encrypten met RSA. Er zijn 256 mogelijkheden, dus we moeten pq>256. Neem
1) priem 1: p=17 dan p-1=16 priem 2: q=23 dan q-1 22 2) pq=17.23=391 (p-1)(q-1)=16.22=352 3) ontbinden van 352 levert 352=2.2.2.2.2.11 [onder linux: factor 352 ] We kunnen nu een E kiezen zdd E<391 en die geen priemfactoren gemeenschappelijk heeft met 352 bijvoorbeeld E=3.7.13=273 4) Nu moeten we opzoek naar een D en X die voldoen aan D=(352X+1)/273 Als we dit benaderen dan zien we dat 273D~352X => 280D~350X => 4D~5X Na wat proberen vinden we een oplossing D=49, X=38 (niet interessant). Even testen: 49.273 mod 352 = 13377 mod 352 = 1 [onder linux: echo "(49*273)%352" | bc ] 5) Encrypten met de publieke key, neem bijvoorbeeld de letter A (ascii 65), we krijgen dan met B=65 G=65^273 mod 391 = 286 [onder linux: echo "(65^273)%391" | bc ] 6) Decrypten met de private key, G=286^49 mod 391 = 65 Jaa het klopt! [onder linux: echo "(286^49)%391" | bc ]
Hiermee hebben een afbeelding gemaakt van de getallen (0..390)->(0..390). Nadat we wat tekst hebben geprocessed, is die afbeelding gemakkelijk te ontcijferen. Normaal nemen we de priemfactoren echter heel erg groot, zdd de modulus 1024 bit wordt. De afbeelding is dan heel erg fors. (0..2^1024-1)->(0..2^1024-1). De enige hoop is dus uit de modulus de twee priemgetallen te halen. Echter, dit is een onbegonnen klus, omdat er geen goed algoritme voor is. Het blijft proberen.
Algemeen
RSA tutorial Java and cryptografie Java zonder keystore DER, PEM, pkcs12, .... Overzicht van de verschillende cryptotechnieken een alternative implementatie Hier staat de stap voor stap uitleg voor het maken van private keys, eigen certificaten en eigen CA's: Je wilt goedkoop een certificaat dat door de browser wordt ondersteund