Как хешировать пароли в PHP?php-24

Хеширование паролей — критически важная часть безопасности любого приложения. Вот современные и безопасные подходы.

Рекомендуемые методы

1. Использование password_hash и password_verify

Хеширование:

$password = 'user_password_123';
$hash = password_hash($password, PASSWORD_DEFAULT);
// $hash выглядит как: $2y$10$X5z4WLP3XsAeHd8qjXtC.OqQlYHu6.MhMIt7eMhOqRtJWABt3NQYm

Проверка:

if (password_verify($password, $hash)) {
    // Пароль верный
} else {
    // Пароль неверный
}

2. Настройка алгоритма и стоимости

$options = [
    'cost' => 12, // Время вычисления (чем больше - тем безопаснее)
    // PHP автоматически выберет лучший алгоритм (bcrypt, argon2)
];
$hash = password_hash($password, PASSWORD_DEFAULT, $options);

Почему именно так?

  1. PASSWORD_DEFAULT автоматически выбирает лучший алгоритм:
    • До PHP 7.2: bcrypt
    • PHP 7.2+: bcrypt или argon2 (зависит от версии)
  2. Автоматическая соль — добавляется случайная соль для каждого хеша
  3. Адаптивная сложность — параметр cost регулирует сложность вычислений

Устаревшие/опасные методы

❌ md5() — взламывается мгновенно
❌ sha1() — небезопасно для паролей
❌ crypt() без правильных параметров
❌ самодельные решения

Обновление старых хешей

// При успешной проверке пароля
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
    $newHash = password_hash($password, PASSWORD_DEFAULT);
    // Сохраните $newHash в БД
}

Работа с Pepper

  1. Добавьте секрет в конфиг:

    define('PEPPER', 'your-long-secret-pepper-string');
    
  2. Модифицируйте хеширование:

    $pepperedPassword = hash_hmac('sha256', $password, PEPPER);
    $hash = password_hash($pepperedPassword, PASSWORD_DEFAULT);
    

Полный пример регистрации/авторизации

Регистрация:

function registerUser($username, $password) {
    $hash = password_hash($password, PASSWORD_DEFAULT);
    // Сохраняем $username и $hash в БД
}

Авторизация:

function loginUser($username, $password) {
    // Получаем $hash из БД по $username
    if (password_verify($password, $hash)) {
        if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
            $newHash = password_hash($password, PASSWORD_DEFAULT);
            // Обновляем хеш в БД
        }
        return true; // Успешный вход
    }
    return false;
}

Безопасное хранение

  1. В БД используйте поле CHAR(255) для хранения хеша
  2. Никогда не храните пароли в логах
  3. Используйте prepared statements при работе с БД

Резюмируем:

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