Шифрование хранилища базы данных

SSL/SSH защищает данные, которыми обмениваются клиент и сервер, но не защищает сами данные, хранимые в базе данных. SSL - протокол шифрования на уровне сеанса передачи данных.

В случае, если взломщик получил непосредственный доступ к БД (в обход веб-сервера), он может извлечь интересующие данные или нарушить их целостность, если информация не защищена на уровне самой БД. Шифрование данных - хороший способ предотвратить такую ситуацию, но лишь незначительное количество БД предоставляют такую возможность.

Наиболее простое решение этой проблемы - установить вначале обыкновенный программный пакет для шифрования данных, а затем использовать его в ваших PHP-скриптах. PHP может вам помочь с этой задачей с помощью таких расширений как Mcrypt и Mhash, реализующих довольно большое число алгоритмов шифрования. При таком подходе скрипт вначале шифрует сохраняемые данные, а затем дешифрует их при запросе. Ниже приведены примеры того, как работает шифрование данных в PHP-скриптах.

Хэширование

В случае работы со скрытыми служебными данными, если не требуется их нешифрованное представление (т.е. его не нужно показывать), то, как следствие, можно использовать хэширование. Хорошо известный пример хэширования - хранение криптографического хэша от пароля в БД, вместо хранения оригинального значения.

В PHP 5.5 и выше, функция password позволяет удобно хэшировать конфиденциальные данные и работать с этими хэшами. В 5.3.7+ можно использовать библиотеку »  password_compat.

password_hash() позволяет хэшировать заданную строку самым сильным из доступных алгоритмом и password_verify() проверяет, что заданный пароль бьется с сохраненным в БД хэшем.

Пример #1 Хэширование полей с паролями

<?php

// Сохраняем хэш пароля
$query  sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
            
pg_escape_string($username),
            
password_hash($passwordPASSWORD_DEFAULT));
$result pg_query($connection$query);

// проверка введенного пользователем пароля на корректность
$query sprintf("SELECT pwd FROM users WHERE name='%s';",
            
pg_escape_string($username));
$row pg_fetch_assoc(pg_query($connection$query));

if (
$row && password_verify($password$row['pwd'])) {
    echo 
'Добро пожаловать, ' htmlspecialchars($username) . '!';
} else {
    echo 
'Ошибка авторизации, ' htmlspecialchars($username) . '.';
}

?>

В более старых версиях PHP можно использовать функцию crypt().

Пример #2 Хеширование паролей используя crypt()

<?php

// сохранение хэшированного пароля
// $random_chars получены например использованием /dev/random
$query  sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
            
pg_escape_string($username),
            
pg_escape_string(crypt($password'$2a$07$' $random_chars '$')));
$result pg_query($connection$query);

// проверка введенного пользователем пароля на корректность
$query sprintf("SELECT pwd FROM users WHERE name='%s';",
            
pg_escape_string($username));
$row pg_fetch_assoc(pg_query($connection$query));

if (
$row && crypt($password$row['pwd']) == $row['pwd']) {
    echo 
'Добро пожаловать, ' htmlspecialchars($username) . '!';
} else {
    echo 
'Авторизация не удалась, ' htmlspecialchars($username) . '.';
}

?>