(Q10) Wat is een hash, en wat is een cryptografische hash?Nb. dit is een nogal technisch verhaal, maar essentieel om digitale handtekeningen uit te kunnen leggen. Als je deze FAQ van boven naar beneden leest kun je deze bijdrage desgewenst overslaan, en indien nodig, later nog eens naar terugkijken.
(A) Gewone HashEen
hash is een soort checksum (optelsom) van alle byte-waarden van een bestand van willekeurige lengte. Een hash heeft, in tegenstelling tot een gewone checksum, altijd een vaste lengte (bijvoorbeeld 16 of 32 bits).
Een voorbeeld van een hash is de optelsom van elke waarde van alle bytes in een bestand, en de uitkomst daarvan modulus 10 berekenen. Stel dat de optelsom van een gegeven bestand 83423 bedraagt, dan is "modulus 10" daarvan: 3 (de werking van de modulus functie leg ik uit onderaan Q05). Met andere woorden, de hash is altijd 1 (decimaal) cijfer lang.
Het hoofddoel van een hash is het detecteren van
onopzettelijke wijzigingen in een bestand. Als er door een communicatiefout op een netwerk in dat bestand een letter "a" in een "b" verandert, zal de optelsom 83424 worden, en de hash dus 4.
Hoe gaat zoiets in zijn werk? De verzender van het bestand berekent, vóór verzending, de hash, 3 dus. Hij verstuurt zowel het bestand als de hash (dat ene cijfer) naar de ontvanger. De ontvanger berekent zelf ook de hash, en vergelijkt die met de meegestuurde hash. Als de hashes overeenkomen, terwijl je weet dat er veel communicatiefouten zijn (denk bijv. aan radiocommunicatie over grote afstanden) is de kans ongeveer 10% dat er toch iets misgegaan is. Hoe langer de hash, hoe kleiner de kans dat de meeste fouten onopgemerkt blijven.
Een simpele hash is totaal ongeschikt voor het detecteren van
opzettelijke wijzigingen. Als een aanvaller "onderweg" het bestand in handen krijgt, kan hij ergens een "a" in een "b" veranderen en ergens anders een "q" in een "p" waardoor het ontvangen bestand dezelfde hash (uit het bovenstaande voorbeeld) zal hebben! Op vergelijkbare wijze kan de aanvaller de komma in een bedrag verplaatsen, ook dit levert geen andere hash op!
In de praktijk worden meer geavanceerde hashes gebruikt voor het detecteren van onopzettelijke wijzigingen. Zeer veel gebruikt zijn CRC (Cyclic Redundancy Check) hashes (of checksums). CRC's zijn veel beter (dan een simpele optelsom) in staat om typische fouten bij seriële communicatie (dus ook Ethernet en WiFi) te detecteren. Hoe CRC's precies werken ga ik hier niet op in (zie bijv.
http://en.wikipedia.org/wiki/Cyclic_redundancy_check). Feit is dat het voor een aanvaller niet moeilijk is om een bestand "onderweg" zodanig te wijzigen (naar zijn hand te zetten) dat het dezelfde CRC oplevert.
Zie
http://en.wikipedia.org/wiki/Hash_function voor meer informatie over hash functies in het algemeen.
(B) Cryptografische hashBij een
cryptografische hash is veel meer sprake van
versnijden. Tijdens het berekenen van de cryptografische hash worden de bytes van (een kopie van) het bestand stevig, doch op reproduceerbare wijze, door elkaar gehusseld, waarbij er tevens met de bits in de bytes geschoven wordt.
Wat er precies gebeurt is niet eenvoudig uit te leggen en dat is ook niet nodig voor het begrip. Het gaat erom dat je begrijpt dat voor een
deugdelijke (nog niet geheel gekraakte) cryptografische hash het volgende geldt:
Noodzakelijk voor de veiliigheid:
1. Het is praktisch onmogelijk om twee verschillende bestanden (zowel met minimale als met enorme verschillen) te vinden die dezeldfe hash hebben (als dat gebeurt heet dit een hash
collision en is er geen sprake meer van de deugdelijke cryptografische hash);
2. Je kunt, uitgaande van de hash, niet berekenen wat de inhoud van het oorspronkelijke bestand geweest moet zijn.
Gegeven:
3. Het maakt niet uit hoe lang het bestand is waar je de hash over berekent;
4. De lengte van de hash waarde (in bits) is altijd hetzelfde.
Er bestaan twee, heel verschillende, toepassingen van cyptografische hashes:
- Wachtwoordverificatie (vaststellen of de inloggende gebruiker het bijbehorende wachtwoord kent);
- Bestandsverificatie (vaststellen of een bestand ongewijzigd is).
Bekende voorbeelden van cryptografische hashfuncties zijn MD5, SHA-1 en SHA-2 (Nb. SHA-2 een verzamelnaam voor de volgende individuele crypto hashes: SHA-224, SHA-256, SHA-384 en SHA-512). Meer info over cryptografische hashes vind je hier:
http://en.wikipedia.org/wiki/Cryptographic_hash_function.
Wachtwoordverificatie Bij
wachtwoordverificatie maakt het nauwelijks uit of een cryptografisch hash algoritme "gekraakt" is of niet. Immers, in de praktijk is het wachtwoord veel korter dan de hash. Daarbij is het nauwelijks interessant (en de kans erop is veel kleiner, omdat wachtwoorden meestal korten zijn dan de hash) als een aanvaller een
ander wachtwoord kan vinden dat toevallig dezelfde hash oplevert; de kans dat de aanvaller een (slecht gekozen) wachtwoord raadt, of de database met gehashte wachtwoorden buit maakt, is veel groter.
Bij het gebruik van
unsalted gehaste wachtwoorden kunnen
rainbow tables een rol spelen. Voor het vullen van een rainbow table gebruikt men een bestand met veel voorkomende wachtwoorden en berekent van elk de hash. Als je vervolgens een wachtwoord-hash in handen krijgt kun je die hash waarde opzoeken in de rainbow table. Als je een match vindt heb je
ofwel (enorm grote kans) exact het bijbehorende wachtwoord gevonden,
ofwel (enorm kleine kans) een ander wachtwoord dat toevallig dezelfde hash oplevert (dat is dus tevens een collision). Echter, als de server unsalted hashes opslaat, maakt het niet uit of je het juiste wachtwoord, of iets anders dat toevallig dezelfde hash oplevert, invoert als wachtwoord.
Uitleggen wat salted wachtwoorden precies zijn, voert hier te ver. Zinvol kan zijn dat je begrijpt dat MD5 hashes, mits goed en random gesalt, best bruikbaar zijn op een (web) server waar gebruikers op inloggen. Er bestaat wel een goede reden om geen
snelle cryprografische hash te gebruiken voor hashed passwords: aanvallers kunnen dan relatief snel rainbow tables maken. Het maakt dus weinig uit om MD5 door SHA-1 of SHA-2 te vervangen, allen zijn behoorlijk snel op moderne hardware. Om die reden zie je in bijv.
https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet het advies om speciaal voor hashed password storage ontworpen algoritmes als bcrypt, PBKDF2 or scrypt te gebruiken (bron:
https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet).
BestandsverificatieBij
bestandsverificatie gaat het meestal om grotere bestanden dan de hashlengte. Het is evident dat collisions dan zullen bestaan. Waar het om gaat is hoe moeilijk het is om ze te vinden. Een zeer ernstige zaak is het als een aanvaller een bestaand bestand naar wens kan wijzigen zodanig dat het dezelfde hash oplevert.
Voorbeelden van serieus "gekraakte" cryptografische hash algoritmes voor bestandsverificatie zijn:
-
MD2-
MD4-
MD5Een nog zeer veel gebruikt, doch volgens sommigen al in 2005 gebroken (zie
http://www.schneier.com/blog/archives/2005/02/sha1_broken.html) cryptografisch hash algoritme is
SHA-1. De reden dat cryptografen als Bruce Schneier stellen dat SHA-1 gebroken is, is dat het minder sterk blijkt te zijn dan de uitvinders ervan hadden aangegeven.
Echter, er zijn geen momenteel publicaties die aantonen dat SHA-1 onbruikbaar is. Aan de andere kant is het best mogelijk dat instanties als de NSA en bijv. Chinese inlichtingendiensten SHA-1 veel verder gekraakt hebben dan bekend gemaakt wordt. Het is dus zaak om het gebuik van SHA-1 af te bouwen. Om die reden mogen PKI-overheid certificaten niet meer van SHA-1 (en ouder) gebruik maken.
Om je gerust te stellen, in
http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html staat verder over de aanvallen op SHA-1:
Door Bruce Schneier: If you're a cryptographer, this is a huge deal.
...
For the average Internet user, this news is not a cause for panic. No one is going to be breaking digital signatures or reading encrypted messages anytime soon.
...
Jon Callas, PGP's CTO, put it best: "It's time to walk, but not run, to the fire exits. You don't see smoke, but the fire alarms have gone off."
Maar.... dat artikel is ondertussen wel uit 2005!