MD5加盐的示例(不安全的实现)

假设我们使用 MD5 对密码进行加盐并存储哈希值:

  1. <?php
  2. // 假设我们在数据库中存储盐
  3. $salt = 'random_salt_1234';
  4. // 用户输入的密码
  5. $password = 'user_password';
  6. // 使用 MD5 对密码加盐进行哈希
  7. $hashedPassword = md5($salt . $password);
  8. // 输出哈希值
  9. echo "加盐后的MD5哈希: " . $hashedPassword;

Bcrypt加密的示例(安全的实现)

4.1 使用 PHP 内置函数 password_hash() 加密密码

PHP 提供了 password_hash() 和 password_verify() 函数来简化密码加密和验证,并默认使用 Bcrypt。<?php

  1. // 用户输入的密码
  2. $password = 'user_password';
  3. // 使用 Bcrypt 加密密码(密码哈希化)
  4. $hashedPassword = password_hash($password, PASSWORD_BCRYPT);
  5. // 输出加密后的哈希值
  6. echo "Bcrypt 加密后的密码哈希: " . $hashedPassword;
  • PASSWORD_BCRYPT 是 PHP 内置支持的常用加密算法。
  • password_hash() 会自动生成盐并将其包含在哈希中。

4.2 验证密码

通过password_verify() 可以验证用户输入的密码是否与存储的哈希匹配。<?php

  1. // 用户输入的密码
  2. $passwordInput = 'user_password';
  3. // 存储在数据库中的 Bcrypt 哈希值
  4. $storedHash = '$2y$10$W9.tLl9OG5jRp2NRse8O1.j8e7z9Rr5TefpGhS2/dZnHfjZnx2.LK'; // 示例哈希
  5. // 验证输入密码是否与哈希匹配
  6. if (password_verify($passwordInput, $storedHash)) {
  7. echo "密码验证成功!";
  8. } else {
  9. echo "密码验证失败!";
  10. }

4.3 控制 Bcrypt 的计算成本

Bcrypt 支持设置 工作因子(cost),它决定了计算的复杂度(即哈希计算的时间消耗)。工作因子越大,哈希计算的速度就越慢,暴力破解的难度也越大。

  1. <?php
  2. $password = 'user_password';
  3. // 设置成本因子(工作因子),可以调整计算的复杂度,10 为常见的默认值
  4. $options = [
  5. 'cost' => 12, // 默认 10,增加成本会让计算变慢,提高安全性
  6. ];
  7. // 使用 Bcrypt 加密密码,指定成本因子
  8. $hashedPassword = password_hash($password, PASSWORD_BCRYPT, $options);
  9. echo "加密后的密码哈希:".$hashedPassword;
  • cost 默认为 10,表示哈希计算的复杂度。增加 cost 会使哈希计算更加耗时,增加破解的难度。
  • 可以根据硬件性能适当调整 cost,以确保未来的安全性。

5. 总结:为什么选择 Bcrypt

5.1 MD5加盐的缺点:

  • MD5的脆弱性:容易受到碰撞攻击和暴力破解攻击。
  • 速度过快:使得暴力破解更加容易。
  • 盐管理问题:MD5 本身不内置盐,使用加盐时需要额外的管理。

5.2 Bcrypt的优势:

  • 内置盐:每次加密时都会自动生成盐,避免盐管理问题。
  • 计算速度慢:增加破解的难度,使得暴力破解更加困难。
  • 可调节计算复杂度:通过调整工作因子(cost)可以增加计算的复杂度,应对未来硬件性能的提升。