php怎么给密码加盐

本篇内容介绍了“php怎么给密码加盐”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

10年积累的网站建设、网站制作经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计制作后付款的网站建设流程,更有西塞山免费网站建设让你可以放心的选择与我们合作。

什么叫给密码“加盐”?如何安全的为你的用户密码“加盐”?

在面对这个网络世界的时候,密码安全总是各个公司和用户都非常关心的一个内容,毕竟现在大家不管是休闲娱乐还是学习购物都是通过网上的帐号来进行消费的,所以我们通常会给用户的密码进行加密。在加密的时候,经常会听到“加盐”这个词,这是什么意思呢?

我们通常会将用户的密码进行 Hash 加密,如果不加盐,即使是两层的 md5 都有可能通过彩虹表的方式进行破译。彩虹表就是在网上搜集的各种字符组合的 Hash 加密结果。而加盐,就是人为的通过一组随机字符与用户原密码的组合形成一个新的字符,从而增加破译的难度。就像做饭一样,加点盐味道会更好。

接下来,我们通过代码来演示一种比较安全的加盐方式。

首先,我们建一个简单的用户表。这个表里只有四个字段,在这里仅作为测试使用。

CREATE TABLE `zyblog_test_user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名',
    `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
    `salt` char(4) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '盐',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
 

然后定义两个方式,一个用来生成盐,一个用来生成加盐后的 Hash 密码。

/**
 * 随机生成四位字符串的salt
 * 也可以根据实际情况使用6位或更长的salt
 */
function generateSalt()
{
    // 使用随机方式生成一个四位字符
    $chars = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
    for ($i = 0; $i < 4; $i++) {
        $str .= $chars[mt_rand(0, count($chars) - 1)];
    }
    return $str;
}

/**
 * 密码生成
 * 使用两层hash,将salt加在第二层
 * sha1后再加salt然后再md5
 */
function generateHashPassword($password, $salt)
{
    return md5(sha1($password) . $salt);
}
 

generateSalt() 方法很简单,就是生成一个随机的四位字符的字符串,我们使用大小写加数字的形式生成这个字符串。这就是传说中的“盐”。

接下来我们就可以使用 generateHashPassword() 方法为用户的原密码加盐。在这里我们第一层先使用 sha1() 对原密码进行一次 Hash ,然后使用这个 Hash 值拼接盐字符串后再进行 md5() 加密。最后加密出来的 Hash 值就很难在彩虹表中找到了。即使找到,也只是上层 sha1() 拼接盐字符串的内容,用户的原文密码毕竟还有一层加密。

剩下的就是我们进行出入库的注册登录测试了。

$pdo = new PDO('MySQL:host=localhost;dbname=blog_test;charset=utf8mb4', 'root', '');

$username = 'ZyBlog1';
$password = '123456';

// 注册
function register($username, $password)
{
    global $pdo;

    // 首先判断用户是否已注册
    $pre = $pdo->prepare("SELECT COUNT(id) FROM zyblog_test_user WHERE username = :username");
    $pre->bindParam(':username', $username);
    $pre->execute();
    $result = $pre->fetchColumn();

    // 如果用户名存在,则无法注册
    if ($result > 0) {
        echo '用户名已注册!', PHP_EOL;
        return 0;
    }

    // 生成salt
    $salt = generateSalt();
    // 密码进行加盐hash处理
    $password = generateHashPassword($password, $salt);

    // 插入新用户
    $pre = $pdo->prepare("insert into zyblog_test_user(username, password, salt) values(?, ?, ?)");

    $pre->bindValue(1, $username);
    $pre->bindValue(2, $password);
    $pre->bindValue(3, $salt);

    $pre->execute();

    return $pdo->lastInsertId();
}

$userId = register($username, $password);
if ($userId > 0) {
    echo '注册成功!用户ID为:' . $userId, PHP_EOL;
}

// 注册成功!用户ID为:1

// 查询数据库中的数据
$sth = $pdo->prepare("SELECT * FROM zyblog_test_user");
$sth->execute();

$result = $sth->fetchAll(PDO::FETCH_ASSOC);
print_r($result);

// Array
// (
//     [0] => Array
//         (
//             [id] => 1
//             [username] => ZyBlog1
//             [password] => bbff8283d0f90625015256b742b0e694
//             [salt] => xOkb
//         )

// )

// 登录时验证
function login($username, $password)
{
    global $pdo;
    // 先根据用户名查表
    $pre = $pdo->prepare("SELECT * FROM zyblog_test_user WHERE username = :username");
    $pre->bindParam(':username', $username);
    $pre->execute();
    $result = $pre->fetch(PDO::FETCH_ASSOC);

    // 用户名存在并获得用户信息后
    if ($result) {
        // 根据用户表中的salt字段生成hash密码
        $password = generateHashPassword($password, $result['salt']);

        // 比对hash密码确认登录是否成功
        if ($password == $result['password']) {
            return true;
        }
    }
    return false;
}

$isLogin = login($username, $password);
if ($isLogin) {
    echo '登录成功!', PHP_EOL;
} else {
    echo '登录失败,用户名或密码错误!', PHP_EOL;
}

// 登录成功!

“php怎么给密码加盐”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


分享标题:php怎么给密码加盐
本文地址:http://hbruida.cn/article/ijjchj.html