[PHP] Funkcja hash() - jak jej użyć w praktyce?

Przeglądając manual php:

http://www.php.net/manual/en/function.hash.php

zacząłem zastanawiać się w jaki sposób użyć tej funkcji do zahashowania hasła w pliku config.php tak by przechowywać tam hasło, ale zahashowane. Przechowywanie czystego tekstu z oczywistych względów jest narażeniem bezpieczeństwa.

By wasze instrukcje były bardziej ujednolicone prosiłbym was o pomoc na tym przykładowym pliku config.php:

<?php


ini_set( "display_errors", true );


date_default_timezone_set( "Europe/Warsaw" ); // http://www.php.net/manual/en/timezones.php


define( "DB_DSN", "mysql:host=localhost;dbname=cms" );


define( "DB_USERNAME", "admin" );


define( "DB_PASSWORD", "admin" );


define( "CLASS_PATH", "classes" );


define( "TEMPLATE_PATH", "templates" );


define( "HOMEPAGE_NUM_ARTICLES", 10 );


define( "ADMIN_USERNAME", "editor" );


define( "ADMIN_PASSWORD", "password" );


require( CLASS_PATH . "/Article.php" );




function handleException( $exception ) {


  echo "Sorry, a problem occurred. Please try later.";


  error_log( $exception->getMessage() );


}




set_exception_handler( 'handleException' );


?>

Oczywiście zawarte w przykładzie hasła są przykładowe i chciałbym się łudzić nadzieją, że żaden debil nie używa takich haseł do “zabezpieczania” swoich wytworów :wink:

Nie tędy droga!

Otóż hash() to funkcja skrótu, a Ty i tak potrzebujesz mieć hasło w postaci tekstowej by je podać przy łączeniu z bazą danych. Mógłbyś próbować użyć jakiejś innej funkcji (szyfrującej), ale klucz (służący do szyfrowania / deszyfrowania) też musiałbyś gdzieś trzymać (w tym lub innym pliku .php). Ewentualnie mógłbyś próbować używać szyfrowania niesymetrycznego, ale chyba jest to przerost formy nad treścią.

Ja sugeruję trzymanie pliku konfiguracyjnego (php) poza dostępem do niego przez stronę www - program w PHP ma dostęp do całego drzewa katalogów i jest w stanie zaimportować taki plik bez problemu.

Przechowywanie hasła w bazie danych, które to hasło służyć ma np. do logowania do twojego serwisu:

Ogólnie proponuję użyć hash( ‘sha256’, $string); lub nawet sha512

Jak wygląda użytkowanie czegoś takiego? Ano, najpierw wymyślasz sobie hasło, dajmy na to “tadek”. Teraz próbnie uruchamiasz sobie skrypt:

echo hash(‘sha256’, ‘tadek’);

To co otrzymasz kopiujesz do schowka i wklejasz do pliku. Krok pierwszy zakończony.

Sprawdzanie, czy wpisano poprawnie hasło wygląda następująco:

To co wpisuje użytkownik, traktujesz funkcją hash z algorytmem, którym haszowałeś hasło wcześniej. W naszym przypadku będzie to sha256.

Następnie porównujesz to z tym co masz w pliku zapisane. Czyli mniej więcej tak:

if(hash('sha256', $_POST['haslo']) === $haslo_z_pliku) echo 'wpisano poprawne hasło';

else echo 'wpisano niepoprawne hasło';

Jeszcze hasło, które znajduje się w pliku powinno być wcześniej posolone, czyli przed haszowaniem trzeba dodać do hasła jakiś kilkuznakowy ciąg kilku cyfr i różnych znaków. Jak dodamy te znaki, zahaszujemy i zapiszemy to sprawdzanie będzie wyglądało tak:

if(hash('sha256', $_POST['haslo'].'te_losowe_znaki_ktore_dodalismy_wczesniej_do_hasla_zapisywanego') === $haslo_z_pliku) echo 'wpisano poprawne hasło';

else echo 'wpisano niepoprawne hasło';

__Przechowywanie hasła, które jest wymagane, żeby się gdzieś zalogować:Jeśli trzymasz gdzieś zapisane hasło np. do połączenia z bazą danych to po zahaszowaniu nijak go użyjesz. W takim wypadku, możesz użyć funkcji crypt() lub po prostu mieć plik *.php

<?php

$db_pass = 'fajne_haslo';

?>

I potem używać tylko include();, aby z niego skorzystać. Z zewnątrz do takiego pliku nie można się dostać w taki sposób, żeby coś z niego wyciągnąć, więc hasło jest tu bezpieczne.