Deze aflevering behandelt de “moeilijkere weg” van zelf de sleutels genereren. In de volgende aflevering wordt de eenvoudigere, maar minder veilige weg besproken waar door middel van wachtwoorden alle benodigde sleutels door de programmatuur zelf worden gegenereerd. Als een aanvaller onze sleutel in handen zou krijgen, is er geen sprake meer van geheime communicatie.
1. Hulp ![]()
Als u begint met de OpenSSL commando’s zal het u duizelen. Ter geruststelling kan ik u verzekeren dat u 90% van die commando’s niet zult gebruiken. Verder kan u hulp krijgen van de OpenSSL bibliotheek zelf. U kunt om hulp vragen door “/?” in te toetsen:
>openssl /?
U krijgt dan een aantal subcommando’s te zien. Daar kunt u ook hulp over vragen. Bijvoorbeeld voor het subcommando genrsa:
>openssl genrsa /?
2. Grote getallen ![]()
Voor het coderen en decoderen is de sleutel een groot getal. Dit getal dient op een willekeurige wijze gegenereerd te worden, want als u een makkelijk, keurig getal zou nemen, kan u dat getal beter meteen aan de aanvaller geven. Het genereren van een privé-sleutel/publieke-sleutel sleutelpaar heeft wat meer voeten in de aarde, waar we verderop in deze aflevering op terug zullen komen. Voordat we een paar willekeurige sleutels gaan maken, gaan we eerst een handige notatie van de sleutels invoeren.
3. Hexadecimaal: notatie voor getallen en sleutels ![]()
De computer rekent het snelste met getallen die een “macht van twee” zijn: 2, 4, 8, 16, …. Invoer in een computer en uitvoer uit een computer van getallen kan dan ook het snelste gebeuren met een tweetallig (binair, bits), een viertallig, een achttallig (octaal) of een zestientallig (hexadecimaal) stelsel gebeuren. Bij een tweetallig stelsel wordt de notatie immens lang: bijvoorbeeld decimaal 256 komt overeen met binair 1111111 (8 bits). Bij een 32-tallig systeem weten we niet meer hoe we 32 symbolen zelf moeten noteren. Een mooi compromis, dat in de gehele computerwereld wordt gebruikt, is het zestientallige (hexadecimale) systeem. We hebben dan 16 symbolen nodig voor de decimale getallen 0 tot en met 15. De hexadecimale notatie is: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, en f (kleine of hoofdletters dat maakt niet uit). De hexadecimale notatie voor decimaal “256” is dus “ff” of “FF”. In een hex symbool kunnen we dus 4 bits kwijt. Een 8-bits getal kan worden genoteerd met 2 hexadecimale symbolen, een 16-bits getal wordt aangegeven met 4 hex symbolen.
4. Base64: notatie nodig voor niet-printbare symbolen ![]()
Als u naar uw toetsenbord kijkt, ziet allerlei karakters: de (kleine- en hoofd) letters a-z, de cijfers 0-9, en allerlei leestekens zoals +=?>. Dit zijn alle zogenaamde “printbare karakters”. Er zijn ook een dertigtal (meer precies: 33) niet printbare karakters zoals het karakter “nieuwe regel”, het karakter “tab” en het karakter “correctietoets (backspace)”.
Bestanden waarvan de inhoud geen tekst, maar een binair bestand betreft, zoals een Excel blad of een applicatie kunnen niet als zodanig op het scherm worden getoond of worden geprint. Die bestanden kunnen ook niet worden verstuurd per email, omdat bijvoorbeeld het karakter “nieuwe regel” niet wordt doorgegeven, maar in Internet verbindingen zelfs vaak wordt gewist. Al sinds tientallen jaren is er een standaardverpakking van binaire bestanden die het mogelijk maakt om ze wel over email te versturen. Deze extreem simpele codering heet base64. De meeste van uw email-aanhangsels zijn met base64 gecodeerd.
Cijferteksten zijn binaire teksten en kunnen dus niet worden geprint. Als u dat wel wil, bijvoorbeeld om didactische redenen, is de oplossing om de cijfertekst te verpakken in base64. OpenSSL biedt hiervoor uiteraard de mogelijkheid. Sleutels kunnen worden genoteerd als hexadecimaal, wat ook meestal gebeurt met enkelvoudige sleutels, maar de sleutelparen (publiek-privé) worden meestal in base64 genoteerd.
5. Symmetrische sleutels genereren ![]()
We gaan wat willekeurig getallen (random numbers) genereren met OpenSSL. Ons eerste voorbeeld is een willekeurig getal getrokken uit de getallen lopende van 0 tot en met 65535 (in hexadecimale notatie lopende van 0 tot en met FFFF) . Dat zijn 65536 getallen. 65536 is gelijk aan 256 x 256 = 8 x 8 x 4 x 8 x 8 x 4, komt dus overeen met 16 factoren 2, oftewel 16 bits. Open een MS-DOS venster en navigeer naar OpenSSL en toets in en eindig met <ENTER>
>openssl rand -hex 2
Hiermee laat u een willekeurig getal genereren van 16 bit (2 maal 8 bit) in hex-notatie. OpenSSL werkt meestal met veelvouden van 8 bit. Bij mij is het antwoord van OpenSSL deze keer het hex getal “d14a”.
>d14a
Voor de AES encryptie kan een sleutel tot en met 256 (= 8 x 32) bits worden gebruikt. We genereren nu een AES sleutel:
>openssl rand -hex 32
Bij mij is de uitslag:
>5ca48286b41757f7650a8b1740ce014241d6d4b43033edb4ed4442df1aff2dab
Een indrukwekkend, hexadecimaal genoteerd getal. Dit getal kan zo worden gebruikt als sleutel.
6. Privé-sleutels genereren ![]()
De wiskunde achter het creëren van een publiek-privé sleutelparen is ingewikkeld en dat laten we allemaal over aan OpenSSL. We willen een paar van 256 bits genereren (nu wil OpenSSL bits en geen bytes). Deze sleutelparen zouden we weer als base64 bestanden kunnen opslaan, maar de publieke sleutel wordt vaak ingevoerd in grotere tekstbestanden, certificaten geheten.
Het zou daarom wel handig zijn om de manier van opslag te standaardiseren (als is het maar om zeker te weten dat je niet zo stom bent om je privé-sleutel weg te geven omdat je dacht dat het je publieke sleutel was). Er zijn verschillende wereldstandaarden om de sleutels behorende bij een paar op te slaan. We zullen er twee bespreken. Die twee zijn de meest populaire en worden door OpenSSL ook ondersteund. Dat we twee standaarden nodig hebben is heel logisch. We willen namelijk een standaard waarbij de sleutel als tekst (PEM-standaard) wordt opgeslagen. Bijvoorbeeld om hem later in een ander tekstbestand te plaatsen, zoals gebeurt bij certificaten. Een computer kan een tekstbestand lezen, maar er zijn altijd problemen met de tekens voor nieuwe regels en spaties. Daarom is er ook een afspraak over een binair bestand (DER-standaard) waar de computer veel sneller de sleutel als getal uit kan genereren.
7. Prive sleutels opslaan ![]()
Open een MS-DOS venster en navigeer naar OpenSSL (niet nodig als OpenSSL in PATH staat). Type in:
>openssl genrsa -out e:\privkeys\prive.pem 256
Dat wil zeggen dat u OpenSSL vraagt om een RSA-sleutel (genrsa) te genereren die op te slaan als PEM-bestand (is de standaard-uitvoer) in de map “e:\privkeys\” en met als naam “prive.pem” met 256 bits. U kunt de namen en extensies zelf kiezen, maar het helpt voor uzelf om een PEM bestand de extensie .pem te geven (een aanvaller vindt hem toch wel). Denk ook steeds aan aanhalingstekens als de bovenmappen spaties bevatten. OpenSSL gaat na <ENTER>aan de slag en toont wat puntjes op het scherm. Als u klaar bent zou u een PEM-bestand met een sleutel moeten hebben. En inderdaad met een programma zoals kladblok het bestand geopend en het ziet er zo uit.
De tekst met PRIVATE KEY hoort bij het bestand. Voor de geïnteresseerden onder u: datgene wat tussen die twee regels staan is de privé-sleutel verpakt in base64.
Om didactische reden zal ik een sleutel laten in DER-formaat. Verwacht bagger, want er zullen veel karakters worden gebruikt die niet “printbaar” zijn. Dat is de prijs die je betaalt voor een binair formaat.
>openssl genrsa -out e:\privkeys\prive.der -der 256
Zie de uitkomst in het blauwe venster waar dit “niet-tekst bestand” is geopend in een eenvoudige tekstverwerker: bagger.
U bent nu in staat om een sleutelpaar te genereren waarmee u het echte werk kan doen. Ik adviseer om een paar van 2048 bits te maken en op te slaan. Later zullen we leren hoe deze sleutel te beschermen.
8. Publieke sleutel afleiden ![]()
Zoals u weet kan de publieke sleutel worden afgeleid van een privé-sleutel. Open een MS-DOS venster en navigeer naar de OpenSSL map. Voer in:
>openssl rsa -pubout -in e:\privkeys\prive.pem -out d:\pubkeys\pub.pem
Het programma “rsa” van OpenSSL manipuleert sleutels. Hier wordt het programma verteld om uit het bestand “prive.pem” in de map “e:\privekeys\”, dat een privé-sleutel bevat, de publieke sleutel te halen en die in het bestand “pub.pem” in de map “d:\pubkeys\” op te slaan. Mocht rsa geen goede privé-sleutel aantreffen dat komt er een foutenmelding. In ons geval was er geen foutmelding en bij opening van het bestand pub.pem troffen we de inhoud in zoals in de figuur hieronder te zien is.
WIJ AANVAARDEN GEEN ENKEL RISICO VOOR EVENTUELE SCHADE OF ANDERE NEGATIEVE GEVOLGEN DOOR HET GEBRUIK VAN DOOR ONS GEADVISEERDE OF GEDISTRIBUEERDE SOFTWARE
De volgende aflevering van de Cursus “Veilig digitaal communiceren” zal heten: “Wachtwoorden en wachtzinnen”.
- Zeer amusante, leerzame columns van de guru:
Schneier on Security * - Goedkoop en heel praktisch:
Secure TCP/IP Programming with SSL: Developer’s Guide** - Network Security with OpenSSL ***
- Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More ***
- Definitieve gids van de guru:
Applied Cryptography: Protocols, Algorithms, and Source Code in C, Second Edition **
Niveau: *: geen voorkennis, **: beginnend programmeur, ***: ervaren programmeur


