Root certificaat in je certificate chain?

Als je een certificaat aanvraagt krijg je bij de oplevering daarvan vaak een zip-bestand met daarin het certificaat, één of meer intermediate certificaten en een root-certificaat.

Het is echter raadzaam om het root-certificaat niet in te regelen in de webserver. Dat scheelt namelijk bandbreedte bij het opzetten van de SSL handshake en het voegt niks toe.

Dat zit zo; een browser is standaard voorzien van een verzameling root-certificaten die door de browser worden vertrouwd. Certificaten die zijn uitgegeven met die root-certificaten worden dus ook vertrouwd. En certificaten die zijn uitgegeven door intermediate certificaten die zijn ondertekend met een van de bekende root-certificaten worden ook vertrouwd. Enzovoort. Een certificaat uit een keten waarvan het root-certificaat niet wordt vertrouwd wordt door de browser niet vertrouwd, ook niet als je het meestuurt. Dus waarom zou je het meesturen?

Sterker nog; door het wel mee te sturen zorg je voor extra traffic bij het opzetten van de SSL verbinding. In een setup waar ik aan werkte was er sprake van een keten van in totaal 4 certificaten; het domein-certificaat, 2 intermediate certificaten en 1 rootcertificaat.

Met het volgende commando kon ik zien hoe veel bytes er werden verzonden bij het opzetten van de SSL handshake:

$ echo | openssl s_client -connect www.domein.nl:443 \
2>/dev/null | grep handshake
SSL handshake has read 6107 bytes and written 512 bytes

Volgens OpenSSL waren er dus 6107 bytes ontvangen en 512 bytes verstuurd. Dat lijkt niet veel, maar dat zijn dus al de nodige roundtrips alvorens er ook maar 1 HTTP request kan worden uitgevoerd.

Door het root-certificaat weg te laten uit de certificate chain werd dat al een stuk minder:

$ echo | openssl s_client -connect www.domein.nl:443 \
2>/dev/null | grep handshake
SSL handshake has read 5022 bytes and written 512 bytes

Dat scheelt dus dik 1000 bytes wellicht een aantal roundtrips.

Om te zien hoe veel TCP-pakketjes er worden verstuurd bij het opzetten van een SSL handshake kun je het volgende commando uitvoeren:

# tcpdump -ttttt -i any 'port 443 and host www.domein.nl'

Als je 2 terminal-vensters open hebt op een testclient kun je in de ene de tcpdump starten en in een ander venster kun je een SSL-verbinding opzetten:

openssl s_client -connect www.domein.nl:443

Dit commando blijft ‘hangen’ omdat het na het opzetten van de SSL-connectie wacht op input. Dat geeft je even de tijd om de output van tcpdump te bekijken.

In mijn situatie scheelde dit precies 1 roundtrip en een verwaarloosbare hoeveelheid tijd. Hoewel het in dit geval niet veel oplevert laat ik voortaan de root-certificaten achterwege. Hebben toch geen nut.