Ik heb een aantal dagen terug een inlogsysteem gebruikt voor een nieuw project van mij. Het script heb ik al voor meerdere sites gebruikt en ik snap ook precies hoe het werkt een waar vaak problemen in kunnen zitten. Nu zit ik echter al een aantal dagen met een hardnekkig probleem, en dat is dat het script de mist in gaat bij het vergelijken van de gegenereerde response met het wachtwoord uit de database en de post response.
Hier volgt het script (alles in een document) (sorry voor de lengte
):
Daarnaast maakt het script, zoals je uit de code kan opmaken, gebruik van het Javascript "sha1.js" dat je hier kan vinden:
http://pajhome.org.uk/crypt/md5/sha1src.html
Even een uitleg van het script:
Bij het laden van de pagina wordt telkens een nieuwe, random string van 255 tekens gegenereerd, door de functie parsestring. Deze wordt in het hidden veld gezet en bij het submitten van het inlog formulier wordt het wachtwoord uit zijn veld gehaald, samen met deze random string (challenge) gehashed en als response in de postback gezet. Daarnaast wordt de challenge telkens opgeslagen in een sessie.
Zoals je ziet is dus het enige dat via $_POST verstuurd wordt, de response en gebruikersnaam.
Wanneer de postback gedaan is, wordt er eerst gecontrolleerd of de gebruiker nog steeds hetzelfde IP-adres gebruikt. Als dat zo is, vervolgt het script en maakt het verbinding met de database server en kiest hij de database. Daarna controlleert hij of de gebruikersnaam die is opgegeven wel bestaat dmv mysql_num_rows. Tot zo ver gaat alles goed.
Hierna moet er worden gecontrolleerd of de wachtwoorden uit de database en het opgegeven wachtwoord, overeenkomen.
Het wacthwoord wordt uit de database gehaald en samen met de eerder in een sessie opgeslagen challenge sha1 gehashed. Het resultaat is een response, en als het goed is, is dat precies hetzelfde als de response die je met de postback hebt verkregen en die is aangemaakt door de javascript functie. Hier gaat het dus fout en op een of andere manier, ondanks tientalle controles, actie per actie, gaat het hier fout bij mij en komen de responses telkens maar niet overeen. Ik snap echter totaal niet wáár....
Database structuur
In de database staat gewoon het wachtwoord sha1 gehashed in de column "password" en de gebruikersnaam onder "username".
Kan iemand mij hierbij helpen? Ik kom er even niet meer uit
...
Alvast bedankt!
Hier volgt het script (alles in een document) (sorry voor de lengte
PHP:
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
| <?php session_start(); $hostname = "localhost"; $database = "got"; $username = "gotuser"; $password = "gotpass"; @mysql_pconnect($hostname, $username, $password) or trigger_error(mysql_error(),E_USER_ERROR); @mysql_select_db($database); if( isset( $_SESSION['currentip'] ) && $_SESSION['currentip'] != $_SERVER['REMOTE_ADDR'] ) { session_unset(); session_destroy(); die(); } function parsestring( $lengte ) { srand( ( (double) microtime() ) * 1000000 ); $string = ''; // De parser doet irri met zoveel tekens zonder spaties achter elkaar, dus verdeel ik dit ff over meerdere regels $tekens = 'abcdefghijklmnopqrstuvwxyz'; $tekens .= 'ABCDEFGHIJKLMNOPQRSTUWXYZ'; $tekens .= '01234567890123456789'; for( $i = 0; $i < $lengte; $i++ ) { $string .= $tekens{ rand( 0, ( strlen( $tekens ) - 1 ) ) }; } return $string; } if( isset( $_POST['username'], $_POST['response'], $_SESSION['challenge'] ) ) { $query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "' LIMIT 0,1"; $result = mysql_query( $query ) or trigger_error( mysql_error() ); if( mysql_num_rows( $result ) == 0 ) { echo 'Username bestaat niet'; $login_Failed_Error = true; } else { $fetch = mysql_fetch_assoc( $result ); // ----> HIER gaat het fout <------------------------------------------------------------------------------------ if( sha1( $fetch['password'] . ':' . $_SESSION['challenge'] ) != $_POST['response'] ) { // script eindigt dus altijd hier. echo 'Wachtwoord is niet ok..'; $login_Failed_Error = true; } else { echo 'Ingelogd'; // etc.. } } } if( isset( $_SESSION['currentip'] ) == false ) { $_SESSION['currentip'] = $_SERVER['REMOTE_ADDR']; } $challenge = parsestring( 255 ); $_SESSION['challenge'] = $challenge; ?> <script type="text/javascript" src="./js/hash.js"></script> <script type="text/javascript"> <!-- function createResponse() { document.getElementById( 'response' ).value = hex_sha1( hex_sha1( document.getElementById( 'password' ).value ) + ":" + document.getElementById( 'challenge' ).value ); document.getElementById( 'password' ).value = ""; document.getElementById( 'challenge' ).value = ""; return true; } //--> </script> <?php if (($_SESSION['loggedin'] != TRUE) AND (!isset($_GET['mode']))) { echo 'In order to use your account, you need to log in.<br />Enter your private username and password and submit this form.<hr />'; if ($login_Failed_Error == TRUE) { echo '<div class="error"><img src="./img/embedded/icons/error.gif" alt="Error" align="top" /> It appears you could not be logged in. Please try again.<br />'.$login_Failed_Reason.'</div>'; } ?> <form method="post" action="<?=$_SERVER['PHP_SELF'];?>" onsubmit="return createResponse();"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="125" valign="top"><strong>Username</strong></td> <td><input name="username" type="text" class="logintxt" size="40" /></td> </tr> <tr> <td width="125" valign="top"><strong>Password</strong></td> <td><input type="password" class="logintxt" id="password" size="40" /> <input type="hidden" id="challenge" value="<?php echo $challenge; ?>"> <input type="hidden" name="response" id="response" value=""></td> </tr> <tr> <td width="125" valign="top"><strong>Other</strong></td> <td><label> <input type="checkbox" name="usr_Public" value="true" /> I am using a public computer</label> <br /> <label> <input type="checkbox" name="usr_SetCookie" value="true" /> Keep me logged in</label> <br /></td> </tr> <tr> <td valign="top"> </td> <td><br /> <input type="submit" value="Access" style="font-weight:bold;" /> <input type="button" name="button2" id="button2" value="Register account" onclick="location.href='<?php echo $_SERVER['PHP_SELF']; ?>?mode=register'" /></td> </tr> </table> </form> <?php } ?> |
Daarnaast maakt het script, zoals je uit de code kan opmaken, gebruik van het Javascript "sha1.js" dat je hier kan vinden:
http://pajhome.org.uk/crypt/md5/sha1src.html
Even een uitleg van het script:
Bij het laden van de pagina wordt telkens een nieuwe, random string van 255 tekens gegenereerd, door de functie parsestring. Deze wordt in het hidden veld gezet en bij het submitten van het inlog formulier wordt het wachtwoord uit zijn veld gehaald, samen met deze random string (challenge) gehashed en als response in de postback gezet. Daarnaast wordt de challenge telkens opgeslagen in een sessie.
Zoals je ziet is dus het enige dat via $_POST verstuurd wordt, de response en gebruikersnaam.
Wanneer de postback gedaan is, wordt er eerst gecontrolleerd of de gebruiker nog steeds hetzelfde IP-adres gebruikt. Als dat zo is, vervolgt het script en maakt het verbinding met de database server en kiest hij de database. Daarna controlleert hij of de gebruikersnaam die is opgegeven wel bestaat dmv mysql_num_rows. Tot zo ver gaat alles goed.
Hierna moet er worden gecontrolleerd of de wachtwoorden uit de database en het opgegeven wachtwoord, overeenkomen.
Het wacthwoord wordt uit de database gehaald en samen met de eerder in een sessie opgeslagen challenge sha1 gehashed. Het resultaat is een response, en als het goed is, is dat precies hetzelfde als de response die je met de postback hebt verkregen en die is aangemaakt door de javascript functie. Hier gaat het dus fout en op een of andere manier, ondanks tientalle controles, actie per actie, gaat het hier fout bij mij en komen de responses telkens maar niet overeen. Ik snap echter totaal niet wáár....
Database structuur
In de database staat gewoon het wachtwoord sha1 gehashed in de column "password" en de gebruikersnaam onder "username".
Kan iemand mij hierbij helpen? Ik kom er even niet meer uit
Alvast bedankt!
[ Voor 1% gewijzigd door VR46 op 28-05-2007 19:48 . Reden: database feitjes vergeten ]