- password_hash
- password_verify
Действията се свеждат до създаване на лаконична база данни и подобен php-код.
Създаване на база данни и таблица
-- изтриване на test, ако съществува -- DROP DATABASE `test`; -- създаване на test CREATE DATABASE IF NOT EXISTS `test` CHARACTER SET utf8 COLLATE utf8_general_ci; -- създаване на таблица users CREATE TABLE IF NOT EXISTS `test`.`users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(30) NOT NULL, `password` varchar(60) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; -- въвеждане на инфо INSERT INTO `test`.`users` (`id`, `username`, `password`) VALUES (1, 'profruit', 'butterfly'); -- заявка SELECT * FROM `test`.`users` LIMIT 1;В резултат на поредицата команди получаваме това.
Ясно, че съхранението на пароли в открит вид в базата данни е глупаво. Ела кумчо изяж ме!
Това остава без труд злоумишленик, докопал се до съдържанието на базата. На свой ред ще направим така, че дори паролите да попаднат в ръцете на хакер, те да останат неотключени, като хешираме паролите и добавим към тях ключ с произволен комплект символи.
Създаване на тестови сайт
Копирайте всеки един файл, посочен долу и създайте подобна структура на вашия сървър.Съдържанието на сайта за придобиване на представа.
Файл config.php съдържа константи, а те пък нужните имена и пароли за съединение към конкретната база данни.
config.php
<?php // конфигурация на база данни define("DB_SERVER", "localhost"); define("DB_USER", "johnsmith"); define("DB_PASS", "hackerpassword"); define("DB_NAME", "test");
Файл convert.php хешира паролата.
Той ще извлече паролата от базата данни. Ще я отпечата в браузъра, след което хешира с помощта на функция password_hash() и отново отпечата в браузъра за съпоставка преди-после. На края ще обнови паролата в хеширан вид в базата данни.
Солта (YoKo%jOhn&*;!*1234<butt$>?) е произволен набор от символи, не по-малко от 22 на брой. Тя е поместена в константа SALT и е плод на вашето въобръжение. Солта остава в php-файл, далеч от базата данни и това усложнява задача на злоумишленика. А при повишена параноя може да се изнесе в файл зад пределите на root-директорията на сървъра.
PDO e използвано в качеството на пример и всякакви коментари около него се приветсват. За простота на кода се налага ограничение от изпълнение на този файл само веднъж, иначе ще хеширате отново.
Най-отдолу има хиперлинк, който ще ви отведе към файла за сравнение на паролите. Преминете по него.
convert.php
<?php include ('pdo.inc.php'); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>конвертитане на паролата</title> </head> <body> <p>Парола в чист вид: <?= $password?></p> <p>Парола с сол: <?php // СОЛ - 22 произволни символа DEFINE("SALT", "YoKo%jOhn&*;!*1234<butt$>?"); // хеширане на паролата echo $hashPassword = password_hash($password, PASSWORD_BCRYPT, ['salt' => SALT]); ?> </p> <?php // чист вид // UPDATE `test`.`users` SET `password` = 'butterfly' WHERE `users`.`id` =1; // обновена с сол $sql = "UPDATE users SET password = :password WHERE id = :id"; $istmt = $db->prepare($sql); $istmt->execute([':password' => $hashPassword, ':id' => $id]); ?> <a href="./verify.php?password=">сравнение на паролите</a> </body> </html>
За елегантност и по-удобна читаемост отделяме файл pdo.inc.php, като самостоятелен. Той се включва в началото на convert.php. Коментарите следва да ви ориентират.
pdo.inc.php
<?php // съединение с база данни require ('config.php'); $db = new PDO('mysql:host='.DB_SERVER.';dbname='.DB_NAME, DB_USER, DB_PASS); // заявка и подготовка $sql = "SELECT * FROM users LIMIT 1"; $stmt = $db->prepare($sql); // изпълнение $stmt->execute(); // подстановка на полетата в променливи $stmt->bindColumn('id', $id); $stmt->bindColumn('username', $username); $stmt->bindColumn('password', $password); $stmt->fetch() ?>Резултат от действието на convert.php.
Забележете адреса в статус бара, към когото ще бъдете пренасочени, а там ви очаква следния прозорец на вид.
Този прозорец се изрисува от файл verify.php.
verify.php
<?php include ('mysqli.inc.php'); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>сравнение</title> </head> <body> <?php if(empty($pass_from_url)): ?> <p>въведете парола</p> <?php elseif (password_verify($pass_from_url, $pass_from_db)): ?> <i>вярна парола</i> <?php else: ?> <i>невярна парола</i> <?php endif; ?> </body> </html>
Файлът съпоставя значенията на хешираната парола от базата данни с въведената в адресното поле на браузъра. Работейки по този начин отпада нужда от форма за въвеждане.
mysqli-драйверът е ползван в качеството на пример, в стил процедурен код. А изяществото налага разделяне на php-кода от html в отделен файл mysqli.inc.php. Коментарите по кода ще ви въведат в обстановката.
mysqli.inc.php
<?php // URL заявка $url = @rtrim($_GET['password']); $pass_from_url = isset($_REQUEST['password']) ? $url : ''; if(!empty($pass_from_url)){ // съединение с база данни require ('config.php'); $connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME); // успех на съединението if(mysqli_connect_errno()) { die("Database connection kaput."); } // DB заявка $sql = "SELECT password FROM users LIMIT 1"; $query = mysqli_query($connection, $sql); // обработка на резултата $result = mysqli_fetch_assoc($query); $pass_from_db = $result['password']; // освобождаване на ресурси mysqli_free_result($query); mysqli_close($connection); // въведена парола echo "{$url} е: "; } ?>
И нека пробваме с произволна парола hacker92. Резултат.
А сега въведем вярната парола butterfly.
Bingo!
извор:
Password Hashing
Salted Password Hashing
до нови срещи ^.^
0 Response to "Хеширане на пароли с сол в PHP 5.5"
Публикуване на коментар