相关文章推荐
喝醉的卤蛋  ·  琴定奇緣世界級古典吉他演奏家蒞校演出| ...·  8 月前    · 
光明磊落的登山鞋  ·  新法宝「1910系列」天赋汇总_手机搜狐网·  1 年前    · 
英俊的羊肉串  ·  娱记皇叔的微博_微博·  1 年前    · 
孤独的煎鸡蛋  ·  中国外经贸企业服务网——商务部中国企业境外商 ...·  1 年前    · 
叛逆的沙发  ·  超燃!10部极限类精品电影推荐! - 知乎·  2 年前    · 
小百科  ›  什么叫给密码“加盐”?如何安全的为你的用户密码“加盐”?开发 ...
加盐会计 hash pdo 加盐加密
耍酷的莲藕
6 月前
硬核项目经理

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

腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
圈层
工具
MCP广场
文章/答案/技术大牛
发布
首页
学习
活动
专区
圈层
工具
MCP广场
返回腾讯云官网
硬核项目经理
首页
学习
活动
专区
圈层
工具
MCP广场
返回腾讯云官网
社区首页 > 专栏 > 什么叫给密码“加盐”?如何安全的为你的用户密码“加盐”?

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

作者头像
硬核项目经理
发布 于 2020-06-01 11:47:59
发布 于 2020-06-01 11:47:59
9.4K 0 0
代码可运行
举报
文章被收录于专栏: 硬核项目经理的专栏 硬核项目经理的专栏
运行总次数: 0
代码可运行

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

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

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

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

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

代码语言: javascript
代码 运行次数: 0
运行
复制
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 密码。

代码语言: javascript
代码 运行次数: 0
运行
复制
/**
 * 随机生成四位字符串的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() 拼接盐字符串的内容,用户的原文密码毕竟还有一层加密。

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

代码语言: javascript
代码 运行次数: 0
运行
复制
$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;
 
推荐文章
喝醉的卤蛋  ·  琴定奇緣世界級古典吉他演奏家蒞校演出| 逢甲大學-逢甲週報
8 月前
光明磊落的登山鞋  ·  新法宝「1910系列」天赋汇总_手机搜狐网
1 年前
英俊的羊肉串  ·  娱记皇叔的微博_微博
1 年前
孤独的煎鸡蛋  ·  中国外经贸企业服务网——商务部中国企业境外商务投诉服务中心
1 年前
叛逆的沙发  ·  超燃!10部极限类精品电影推荐! - 知乎
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
小百科 - 百科知识指南
© 2024 ~ 沪ICP备11025650号