inloggen met zout

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jan R

Jan R

13/06/2022 08:55:12
Quote Anchor link
Hoi

Ik logde altijd in met een query zoals hieronder zonder zout :(
Quote:
$qry = '
select
l.id,
l.login,
schermnaam,
hash
from
logins l
where
l.login = "' . mysqli_real_escape_string($con, $_POST['email']) . '" and
(hash="' . hash('sha512', $_POST['pw']) . '") and
true
';

Ik zou echter de veiligheid willen verhogen en ook de salt bijvoegen.

Ik weet password_verify en password_hash maar zie niet onmiddellijk hoe te implementeren in de inlogquery.
De wachtwoord wijzigenquery, OK dat kan maar inloggen?

Hoe doen jullie dat?

Wat gebruiken jullie zoal als zout? Woorden, afkortingen, speciale tekens, het systeem(de functie) zelf laten aanmaken, zelf iets maken via random generator?

Hoe zonder zout converteren naar met zout zonder veel last voor de gebruikers?

Jan
 
PHP hulp

PHP hulp

30/12/2024 18:14:26
 
Adoptive Solution

Adoptive Solution

13/06/2022 09:13:30
Quote Anchor link
Dit is een mogelijkheid :

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
$i      = 10;
$salt   = bin2hex( openssl_random_pseudo_bytes( $i, $cstrong ) );
$salted = $salt . '_' . $password;

$md5Pass  = md5( $salted );
$hashPass = password_hash( $salted, PASSWORD_BCRYPT);
$gostPass = hash( 'gost', $salted );


Meer info :

https://crackstation.net/hashing-security.htm

Weet dat password_hash al een salt van zichzelf heeft. Je hoeft dat dus niet extra toe te voegen, tenzij je paranoide bent.

En een gebruiker staat daar buiten.
 
Jan R

Jan R

14/06/2022 07:14:41
Quote Anchor link
Ok dat lukt om een (extra)salt aan te maken maar hiermee kan je niet inloggen.
Waarom de lijn $md5Pass = md5( $salted );? Daarna doe je niets meer met $md5Pass.
 
Adoptive Solution

Adoptive Solution

14/06/2022 10:30:49
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php

// Komt van webpagina

$_POST['naam']   = 'Bakker Bart';
$_POST['plaats'] = 'Hindelopen';

$_POST['username'] = 'Dirk';
$_POST['password'] = 'wachtwoord';

// Aanmelden/Registreren verwerken

$naam     = $_POST['naam'];
$plaats   = $_POST['plaats'];
$username = $_POST['username'];
$password = $_POST['password'];

// Toevoegen database

$i      = 10;
$salt   = bin2hex( openssl_random_pseudo_bytes( $i, $cstrong ) );
$salted = $salt . '_' . $password;

$hash  = md5( $salted ); // of een ander hash algoritme

$query = "INSERT INTO leden ( naam, plaats, username, salt, hash ) VALUES ( '$naam', '$plaats', '$username', '$salt', '$hash' )";

// Opvragen bij login

$query = "SELECT naam, plaats, username, salt, hash FROM leden WHERE username = '$username'";

// dan data controleren

if( $row->hash == md5( $row->salt . '_' . $password ) )
{

    // ga verder
    
} else {
    // fout
}

// ....

?>
Gewijzigd op 14/06/2022 11:17:09 door Adoptive Solution
 
Jan R

Jan R

14/06/2022 12:37:02
Quote Anchor link
OK Nu begrijp ik wat je bedoelt.
Na ophalen van het record moet ik nog steeds de hash controleren. Dat was echter wat ik net probeerde te vermijden. Mijn query controleert in 1 beweging wachtwoord en login en dat wou ik behouden. Mogelijks is dit onmogelijk.

PS Ik werk momenteel met bedrijfscomputer en vermelde site https://crackstation.net/hashing-security.htm is verboden!

Jan
 
Ivo P

Ivo P

14/06/2022 15:24:27
Quote Anchor link
Dit zou moeten werken
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$query
= "SELECT naam, plaats, username, salt, hash
          FROM leden
          WHERE username = '$username'
            AND MD5(CONCAT(salt, '_', '$password') = hash
          "
;
?>


Maar de vraag is of je database dan wel zo slim is om dat te optimaliseren en alleen voor dat ene record met username = '$suername' de hash te bepalen en niet voor alle 10.000 records in je database.
 
Jan R

Jan R

16/06/2022 09:32:40
Quote Anchor link
Allen alvast bedankt voor de hulp zover.

Ik ga dan toch maar werken met de password_verify en controleren via php. Sinds php 8.0 gebruikt deze standaard zijn eigen zoutvaatje.

Ik stel wel vast dat de lengte veel kleiner is dan via hash('sha512', $_POST['pw']). Slechts 60 of 97 ipv 128 en bevat ook nog de salt. Is dit dan nog wel veilig denk ik dan.

Welke hash zou ik het best gebruiken?
PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I of PASSWORD_ARGON2ID en eventuele extra opties. Ik wil een goede beveiliging :)

Jan
 
Adoptive Solution

Adoptive Solution

16/06/2022 09:56:02
Quote Anchor link
Voeg dit toe aan mijn eerdere code.
Het toont alle hashes men hun lengte.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h3>Hash lengte</h3>

<pre>
<?php
$data
= $salted;

$r = crypt( $data );
printf("%-12s %3d %s\n", 'crypt', strlen($r), $r);

$r = password_hash( $data, PASSWORD_BCRYPT );
printf("%-12s %3d %s\n", 'bcrypt', strlen($r), $r);

foreach ( hash_algos() as $v )
{

    $r = hash( $v, $data, false );
    printf("%-12s %3d %s\n", $v, strlen($r), $r);
}

?>

</pre>


En dit kan je apart gebruiken of ook toevoegen.
Het rekent uit hoe lang een hash algo erover doet.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<pre>

<?php
$curTime
= microtime(true);

echo 'Building random data ...' . PHP_EOL;
@
ob_flush();flush();

$data = '';
for ($i = 0; $i < 64000; $i++)
    $data .= hash('md5', rand(), true);

echo strlen($data) . ' bytes of random data built !' . PHP_EOL . PHP_EOL . 'Testing hash algorithms ...' . PHP_EOL;
@
ob_flush();flush();

$results = array();

$v = 'crypt';
echo $v . PHP_EOL;
@
ob_flush();flush();
$time = microtime(true);
crypt( $data );
$time = microtime(true) - $time;
$results[$time * 1000000000][] = "$v ( crypt() )";

$v = 'bcrypt';
echo $v . PHP_EOL;
@
ob_flush();flush();
$time = microtime(true);
password_hash( $data, PASSWORD_BCRYPT );
$time = microtime(true) - $time;
$results[$time * 1000000000][] = "$v ( password_hash() )";

$v = 'md5';
echo $v . PHP_EOL;
@
ob_flush();flush();
$time = microtime(true);
md5( $data );
$time = microtime(true) - $time;
$results[$time * 1000000000][] = "$v ( md5() )";

foreach (hash_algos() as $v) {
    echo $v . PHP_EOL;
    @
ob_flush();flush();
    $time = microtime(true);
    hash($v, $data, false);
    $time = microtime(true) - $time;
    $results[$time * 1000000000][] = "$v (hex)";
    $time = microtime(true);
    hash($v, $data, true);
    $time = microtime(true) - $time;
    $results[$time * 1000000000][] = "$v (raw)";
}


ksort($results);

echo PHP_EOL . PHP_EOL . 'Results: ' . PHP_EOL;

$i = 1;
foreach ($results as $k => $v)
    foreach ($v as $k1 => $v1)
        echo ' ' . str_pad($i++ . '.', 4, ' ', STR_PAD_LEFT) . '  ' . str_pad($v1, 30, ' ') . ($k / 1000) . ' microseconds' . PHP_EOL;

?>


</pre>



<?php
echo '<p>Begintijd : ' . $curTime . '<br />';
echo 'Eindtijd : ' . microtime(true) . '<br />';
$timeConsumed = round(microtime(true) - $curTime,3);
echo 'Duur : ' .  $timeConsumed . '</p>';

$d = date("H:i:s.u", microtime(true) - $curTime );
echo $d;
?>


Bron : Zie https://www.php.net/manual/en/function.hash.php

En password hash bevatte al voor php 8 zout.
 
Jan R

Jan R

16/06/2022 10:21:04
Quote Anchor link
Bedankt Het is ook daar dat ik de info haal en ook op w3school en niet te vergeten HIER.

Maar het is me niet zozeer de tijd welke me interesseert. Er logt toch zelden meer dan 1 persoon in terzelfder tijd. De veiligheid is dus veel belangrijker.
password_hash ondersteunt dus slechts 4 mogelijkheden momenteel. Wat zou daarvan dus de beste zijn?

Jan
 

16/06/2022 11:44:29
Quote Anchor link
Alles is beter dan wat je had, met MD5. Daarvoor zijn zelfs rainbow tables om de beveiliging mee te kraken.
Gebruik vooral password_hash() en password_verify().

Als je het in één keer wilt kunnen controleren, dan heb je een database nodig die dat ondersteunt, zoals PostgreSQL in combinatie met de extensie pgcrypto. Hiermee kan je direct wachtwoorden controleren die met password_hash() en BCRYPT zijn gemaakt. Een voorbeeld vind je hier: https://stackoverflow.com/questions/55557494/use-pgcrypto-to-verify-passwords-generated-by-password-hash .

"one may take the hash generated by PHP's password_hash, replace the leading $2y$ by $2a$ and pass it as the second argument of pgcrypto's crypt()."
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
postgres=# \set hash '$2a$10$fD2cw7T6s4dPvk1SFHmiJeRRaegalE/Oa3zSD6.x5WncQJC9wtCAS'

postgres=# SELECT crypt('hello', :'hash') = :'hash'
 ?column?
----------
 t
 
Jan R

Jan R

16/06/2022 13:44:07
Quote Anchor link
Mijn oorspronkelijke hash in dit topic was met sha512. Echter zonder salt.

Één van mijn 1° vragen hier op het forum jaren geleden en was ongeveer dezelfde vraag als nu. Toen kreeg ik sha512 als antwoord.

Welke optie zou ik nu moeten kiezen voor de beste veiligheid? PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I of PASSWORD_ARGON2ID

Volgens de help kan "standaard" bij elke php versie wijzigen.
 
Ward van der Put
Moderator

Ward van der Put

16/06/2022 21:36:01
Quote Anchor link
Aan de $2y$10$ in de string van password_hash() kun je zien dat PASSWORD_DEFAULT en PASSWORD_BCRYPT op dit moment beide BCrypt gebruiken met een work factor van 10.

De keuze is vooral: mocht er in de toekomst een sterkere encryptie nodig zijn, dan wordt die bij PASSWORD_DEFAULT door PHP geregeld en moet je dat bij PASSWORD_BCRYPT zelf regelen.
 
Jan R

Jan R

16/06/2022 22:21:05
Quote Anchor link
Conclusie is dus dat default goed is!

Allen bedankt.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.