Hi,

Momenteel werk ik met hash('sha512', $pw) voor mijn paswoorden. Is er iets beter en is het de moeite om over te stappen bij een bestaand project.
volgens http://php.net/manual/en/function.hash.php zijn er zo veel mogelijkheden om uit te kiezen maar de sterkte is niet vermeld.

Jan
Ik vind het tof dat je een heel verhaal vertelt ... maar waar reageer je nu eigenlijk precies op? Wat ik zeg is dat een "bekend" wachtwoord, laten we het voor het gemak even zo noemen, makkelijk gevonden wordt als dat gehasht is met MD5 dan met bijv. password_hash.

Wat klopt daar niet aan?
Het wordt niet gevonden in de zin van "berekend", het is gewoon een hash-wachtwoord paar dat wordt opgeslagen. Als het bekend is hoe er gehashed wordt met password_hash() is dit even (on)veilig. (actually, dit maakt niet eens uit want alle informatie wordt in de hash opgeslagen) Het enige verschil is dat je wellicht wat langer moet rekenen voordat je kunt constateren dat twee hashes equivalent zijn. Je kunt nog steeds dezelfde dictionary attack gebruiken. Dit is letterlijk lood om oud ijzer. Nogmaals, een sterker hashing algoritme maakt een zwak/bekend wachtwoord niet opeens veiliger.

Ik weet echt niet hoe ik dit eenvoudiger moet uitleggen.
>> Het wordt niet gevonden in de zin van "berekend"

Ja, dat klopt ... er is als het ware een heeeeel groot woordenboek met bekende hashes en de daarbij behorende vertalingen. Hoe het gevonden wordt boeit niet. Het feit is dat er heel veel wachtwoorden bekend zijn wat MD5 dus in gebruik onveiliger gemaakt in de zin van dat een wachtwoord makkelijker is te herleiden.

>> Als het bekend is hoe er gehashed wordt met password_hash() is dit even (on)veilig.

Nou nee, bij iedere generering ontstaat een andere hash. Jij en ik kunnen hetzelfde wachtwoord hebben en toch een totaal andere hash.
.............. die je controleert met password_verify(). Het maakt wat dat betreft niet uit of de hashes hetzelfde zijn of niet.

Je gebruikt nog steeds de oorspronkelijke wachtwoorden in de dictionary attack... en je loopt nog steeds gewoon die lijst af...

Het wordt een ander verhaal als je ook een salt gebruikt. <-- hmm maakt dit uberhaupt uit?
Zover ik heb begrepen, correct me gerust if I'm wrong, levert MD5 altijd dezelfde hash op. Dus als wij beiden hetzelfde wachtwoord hebben kun je bij MD5 aan de hash zien wat het wachtwoord is.

Als je password_hash gebruikt hebben wij beiden een andere hash. Er is dus niet meer een vaste hash voor het wachtwoord "geheim" en dus kun je aan mijn of jouw hash niet zien wat het wachtwoord is.
Ja dat zeg ik dus. Je gebruikt "geheim" als password en de hash die je hebt gestolen en kijkt dan of password_verify() iets oplevert.
Maar dat is dus iets totaal anders dan wat er met MD5 gebeurt.

Bij MD5 is het:

xyz123 = geheim

Wat jij nu zegt is:

xyz123 => laten we het eens matchen met 'geheim' en kijken of daar toevallig een hit uitkomt.
Ja, dat is wat password_verify() doet bruh.

<?php
$password = 'welkom'; // zwak wachtwoord

$iterations = 10;
for ($i=0; $i < $iterations; $i++) {
    echo password_hash($password, PASSWORD_BCRYPT).'<br>';
}
/*
$2y$10$HrPMcjHoVYsKC7GtFmfKbOS92SvIV/pcMHu/luU4frGCYkO1FQt9S
$2y$10$Auf4NqsVJqD00MA6IOHbH.PWv86sMl83457Tjo3zTyNmHFUVaKQfe
$2y$10$/tdj793VKJqHs4XdK4xeVedEyesngnyEP3oK1Wxf8Nn9xoyzQV33G
$2y$10$Yh1PWzYUajfC22G7AfrFguOmtKzWMyAje5kBb.eSABLbn7OzDRHa2
$2y$10$.hh77fACFTwiJb9ho7U32OAOgONanCEjtt3sR2Q7CBUir8CwesEJe
$2y$10$V6cop8P.5QU4ab.17u429Og6cIXO1wy11gltwdCOEKy56dpBFxPqq <--- pak deze bijvoorbeeld
$2y$10$oq.KXHnrvABH3FkiUFw.x.lCFN5BkAcPltdgKR8UhoeLqk4HDLaaO
$2y$10$DiQTJsPXoq8ZUc4mmtEE8udqTelNBYe6Ge8/.0dTWceq1BJt/6m4G
$2y$10$B5NMUBYkds3hLxORmqr/4e8rrDQOydxPoIvkYHzWWQI9gIcQH0yv6
$2y$10$hV1cvprUKExjfKOf.Yz9m.1rvmISJJNUo5bI.njdQYx68hydrBiou
*/

// Dit wordt gestolen
$stolenHash = '$2y$10$V6cop8P.5QU4ab.17u429Og6cIXO1wy11gltwdCOEKy56dpBFxPqq';

// Nou dan pakken we het woordenboek erbij...
$dictionary = array(
    'geheim',
    'welkom',
    'lol',
);

// dictionary attack bij zwak wachtwoord werkt nog steeds hetzelfde
foreach ($dictionary as $candidate) {
    echo $candidate.': ';
    if (password_verify($candidate, $stolenHash)) {
        echo 'pass';
    } else {
        echo 'fail';
    }
    echo '<br>';
}
/*
geheim: fail
welkom: pass
lol: fail
*/
?>


Dus nogmaals: je doet er verstandiger aan te investeren in een strategie die sterke wachtwoorden oplevert, want een sterkere hashing lost het probleem met zwakke wachtwoorden niet op...
Ik snap wel wat je bedoelt, maar je snapt toch dat de approach anders is?

Laten we even doen alsof het gehashte wachtwoord een woord in een vreemde taal is. Laten we zeggen 'sojeojekre'.

Nu pak ik m'n MD5 woordenboek erbij, ga naar de letter 's' ... 'so' ... 'soj'... ah daar staat het. De vertaling (het originele wachtwoord) is 'amigo'.

Nu wil jij ook weten wat 'sojeojekre' betekent, maar jij moet nu eerst miljoenen mogelijke wachtwoorden gaan afvuren om te kijken of er misschien een match is.

Stel dat een hacker nu een database heeft onderschept met 100.000 wachtwoorden, dan moet ie in het geval van password_hash 100.000 keer miljoenen wachtwoorden gaan afschieten, terwijl ie ze met MD5 gewoon stuk voor stuk in het 'woordenboek' kan opzoeken en dan is ie met 100.000 zoekopdrachten klaar. En dan heb ik de cost factor van password_verify nog even buiten beschouwing gelaten.
Ik heb het nog steeds over een wachtwoordenbibliotheek, geen hash lookup. Ja, je vindt een zwak wachtwoord niet direct maar wel veel sneller dan de bedoeling is. Het is nog steeds lineair? Je hebt de hash, loop maar door de bekende wachtwoorden heen.

Zie ook de toevoeging in de vorige reactie:
Dus nogmaals: je doet er verstandiger aan te investeren in een strategie die sterke(re) wachtwoorden oplevert, want een sterkere hashing lost het probleem met zwakke wachtwoorden niet op...

Reageren