* Упражнение 2, 2015
Публикувано на 18 март 2015 в раздел ОСУП.
В това упражнение показваме login форма. Паролите са хеширани със salt (уникален ключ за всеки потребител в базата) и pepper (един общ salt в кода).
База от данни - мястото, където ще записваме потребителските имена и пароли. Създаваме си уникален потребител специално за login формата.
CREATE DATABASE upr2; USE upr2 CREATE TABLE users( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user VARCHAR(64) NOT NULL UNIQUE, pass CHAR(96) NOT NULL, salt CHAR(96) NOT NULL ); GRANT SELECT ON upr2.users TO loginform@localhost IDENTIFIED BY 'fghjudighfduishgiufdsw';
passgen.php - използвайте този скрипт, за да си генерирате insert заявки за вмъкване на потребители в базата данни
<?php DEFINE("PEPPER", 'jfrikl^#@&*wsa^$#&*gjr__--eiu--AAa'); DEFINE("KEYSTRECHITERATIONS", 100000); $user = "ivan"; $pass = "123456"; // Този salt определено е прекалено дълъг // може да използвате значително по-къс // без това да навреди на сигурността $salt = base64_encode(openssl_random_pseudo_bytes(72)); for($i=0; $i<KEYSTRECHITERATIONS; $i++){ $pass = hash("sha384", $salt.$pass.PEPPER); } echo "INSERT INTO users(user, pass, salt) VALUES('".$user."', '".$pass."', '".$salt."')"; ?>
index.php - главната страница на сайта, в която показваме формата за вход.
<?php session_start(); ?> <html><head><title>Login page</title></head> <body> <form action="login.php" method="POST"> USER: <input type="text" name="user" /><br /> PASS: <input type="password" name="pass" /><br /> <input type="submit" name="loginbutton" value="Login!" /><br /> </form><br /> <?php if(isset($_SESSION['error'])){ echo $_SESSION['error']; session_unset(); session_destroy(); } ?> </body></html>
login.php - скрипта, който извършва автентикацията.
<?php DEFINE("DBHOST", "localhost"); DEFINE("DBUSER", "loginform"); DEFINE("DBPASS", "fghjudighfduishgiufdsw"); DEFINE("DBNAME", "upr2"); DEFINE("PEPPER", 'jfrikl^#@&*wsa^$#&*gjr__--eiu--AAa'); DEFINE("HASHALGO", "sha384"); DEFINE("KEYSTRECHITERATIONS", 100000); // Проверява дали има попълнена форма function POSTVarsExists(){ return (isset($_POST['user']) && isset($_POST['pass']) && isset($_POST['loginbutton'])); } // Проверява за валиден формат на името и паролата // Приели сме потребителски имена от 4 до 64 букви/цифри // и пароли от 6 до 64 символа (каквито и да е). function userAndPassAreValidFormat($user, $pass){ return (is_string($user) && is_string($pass) && strlen($pass)>=6 && strlen($pass)<=64 && preg_match("/^[a-zA-Z0-9_-]{4,64}$/",$user)); } // С тази функция се пренасочваме обратно към index.php function backToIndex($error){ switch($error){ case 0: break; case 1: session_start(); session_unset(); $_SESSION['error'] = "Invalid username OR password"; break; case 2: session_start(); session_unset(); $_SESSION['error'] = "Technical issues. Come back later"; break; } header("Location: index.php"); } // Ако не сме попълнили форма, се връщаме към index if(!POSTVarsExists()){ backToIndex(0);; exit; } // Ако сме попълнили име или парола, които не отговарят // на стандартния формат, се връщаме към index с грешка if(!userAndPassAreValidFormat( $_POST['user'], $_POST['pass'] )){ backToIndex(1); exit; } $user = $_POST['user']; $pass = $_POST['pass']; // Свързване с базата от данни $link = @mysqli_connect(DBHOST,DBUSER,DBPASS,DBNAME); if(!$link){ backToIndex(2); exit; } // Това може да се пропусне $user = @mysqli_real_escape_string($link, $user); // Изпълняваме SQL заявка $sql = "SELECT id, pass, salt FROM users WHERE '".$user."' = user LIMIT 1"; $result = @mysqli_query($link, $sql); if(!$result){ backToIndex(2); @mysqli_close($link); exit; } // Взимаме ред от резултата от заявката $row = @mysqli_fetch_assoc($result); // Ако няма върнат ред, това е невалидно име/парола if(!isset($row['id'])){ backToIndex(1); @mysqli_close($link); exit; } // Хешираме подадената от потребителя парола for($i=0; $i<KEYSTRECHITERATIONS; $i++){ $pass = hash(HASHALGO, $row['salt'].$pass.PEPPER); } // Ако не съвпада с паролата от БД, връщаме към index if($pass !== $row['pass']){ backToIndex(1); @mysqli_close($link); exit; } // Ако всичко е наред, продължаваме към securearea session_start(); session_unset(); session_regenerate_id(true); $_SESSION['userid'] = $row['id']; header("Location: securearea.php"); exit; ?>
securearea.php - мястото, където искаме да влезнем.
<?php session_start(); if(!isset($_SESSION['userid'])){ header("Location: index.php"); exit; } ?> <html><head><title>Secure area</title></head> <body> <?= "Hello ".$_SESSION['userid'] ?> </body></html>
Добави коментар