Zout toevoegen bij registratie
Je weet dus al dat hashen via
md5 - een onomkeerbaar proces is en een hacker
die toegang krijgt tot de hash, niet in staat zal zijn
om het wachtwoord uit deze hash te halen.
Eigenlijk is deze bewering niet helemaal correct - tegenwoordig hebben kwaadaardige hackers bibliotheken samengesteld met hashes van populaire en minder populaire wachtwoorden en elke dwaas kan een wachtwoord achterhalen, simpelweg door de hash te googelen.
Het gaat hier om redelijk eenvoudige, populaire wachtwoorden.
Google bijvoorbeeld eens naar de hash 827ccb0eea8a706c4c34a16891f84e7b
en je zult direct in de zoekresultaten van Google zien dat dit
het wachtwoord '12345' is.
Hashes van voldoende complexe wachtwoorden zijn op deze manier niet te achterhalen (probeer maar).
Je zou kunnen vragen, wat is dan het probleem - laten we ons allemaal registreren met complexe wachtwoorden. Er is echter een probleem - de meeste gebruikers denken niet na over de veiligheid van hun gegevens en kunnen redelijk eenvoudige wachtwoorden invoeren.
We kunnen bij registratie eisen dat er langere
wachtwoorden worden bedacht, door bijvoorbeeld
het minimum aantal tekens te beperken tot 6
of 8, echter, er zullen altijd wachtwoorden
verschijnen zoals '123456' of '12345678'.
We kunnen natuurlijk een slimmer algoritme bedenken om de complexiteit van het wachtwoord te controleren, maar er is een andere oplossing.
De essentie van deze oplossing is als volgt: wachtwoorden moeten worden gezouten. Zout is een speciale willekeurige string, die aan het wachtwoord wordt toegevoegd bij registratie en de hash wordt dan niet berekend van het simpele wachtwoord, maar van de string zout+wachtwoord, dus van het gezouten wachtwoord.
Dat betekent dat je bij registratie iets dergelijks zult doen:
<?php
$salt = '1sJg3hfdf'; // zout - complexe willekeurige string
$password = md5($salt . $_POST['password']); // transformeer wachtwoord naar gezouten hash
?>
Hierbij zal de zout verschillend zijn voor elke gebruiker, deze moet willekeurig gegenereerd worden op het moment van registratie.
Hier is een kant-en-klare functie die dit doet:
<?php
function generateSalt()
{
$salt = '';
$saltLength = 8; // lengte van de zout
for($i = 0; $i < $saltLength; $i++) {
$salt .= chr(mt_rand(33, 126)); // teken uit ASCII-tabel
}
return $salt;
}
?>
Met deze functie kunnen we onze code als volgt herschrijven:
<?php
$salt = generateSalt(); // zout
$password = md5($salt . $_POST['password']); // gezouten wachtwoord
?>
Ik herhaal nogmaals dat dit wijzigingen waren bij registratie - in de database slaan we niet simpelweg de hash van het wachtwoord op, maar de hash van het gezouten wachtwoord.
Dat is nog niet alles: in de tabel met gebruikers, naast
de velden login en password, moet
er ook een veld salt komen, waarin
we de zout van elke gebruiker opslaan.
Implementeer de hierboven beschreven registratie met gezouten wachtwoord.