php对用户密码进行加密技巧实例
发布:smiling 来源: PHP粉丝网 添加日期:2024-03-10 11:34:07 浏览: 评论:0
密码验证是很常见的需求,如何在实现功能之余,防止用户密码泄露,已经有了很成熟的方案。这篇文章把自己的思考和结论做一下记录。
对用户密码进行加密时需要做到:
防止用户密码明文被窃听
1.交给https,明文传输。
2.客户端将密码加盐(盐随机生成、具有强度)并哈希。服务端再次加盐哈希并对比。假设https被窃听,攻击者破解密码明文也具有相当难度。
防止数据库被攻破时,用户密码明文被窃取。
1.增加哈希算法强度。
2.随机生成具有强度的盐。
一些思考
哈希算法是不可逆的。攻击者可以生成海量的密码 -> 哈希值键值对,反向映射,有概率通过哈希值得到密码。
故,破解的成本=哈希算法强度×盐值数量。
如何选择哈希算法强度
计算耗时用户可接受(视应用场景,如0.2S内)。
计算耗时尽量长,即增加哈希算法强度。
为什么盐要随机
如果盐不随机,攻击者可以针对单个盐生成哈希值->密码键值对,再对整个数据库的哈希值做匹配。
假设盐是保密的,盐可能因为各种原因被攻击者获取(代码泄漏、社会工程学等等)。
攻击者也可以通过在数据库被攻破的网站上注册用户,通过 哈希值->攻击者密码+盐 来破解盐。
为什么盐要有强度
如果盐的强度(长度)不够。攻击者可以建立多个 哈希值->密码 数据库,简单盐被匹配(攻破)的概率更高。
为什么盐可以明文存储
攻击者很难有足够的计算资源和存储空间建立海量的 哈希值->密码 数据库,针对单条用户记录,建立 哈希值->密码 数据库进行攻击的成本过高。
php的实现
最初的想法
需求是房间密码,出于简单考虑,我最初的想法是,MD5+随机盐。
在数据库里大致是这样:
- +-------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+-------+
- | uid | int(11) | NO | PRI | NULL | |
- | pwd | varchar(45) | YES | | NULL | |
- | salt | varchar(45) | YES | | NULL | |
- +-------+-------------+------+-----+---------+-------+
php的推荐实现
php的md5文档
https://www.php.net/manual/zh/function.md5.php
给了一个很好的指引:
https://www.php.net/manual/zh/faq.passwords.php#faq.passwords.fasthash
password_hash 和 crypt 函数返回值的组成部分,依次为:所选择的算法,算法选项,所使用的“盐”,以及散列后的密码。
更改后、数据库表变为:
- +-------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+-------+
- | uid | int(11) | NO | PRI | NULL | |
- | pwd | varchar(255) | YES | | NULL | |
- +-------+-------------+------+-----+---------+-------+
相较之前的方案:
1.记录了采用的算法(可以在不改动代码的情况下升级算法)
2.记录了采用算法的cost(强度),可以在硬件计算能力上升的情况下,调整cost来维持安全性。
3.盐和哈希值一并返回,简化了接口调用、数据库存储。
php的验证接口设计得相当漂亮。
使用简单,强制调用者使用随机的salt(不容易误用),可在不修改代码的情况下拓展算法强度。
代码:
- if (!emptyempty($xxxx_info['pwd'])) { // 若原来有密码,则要检测
- if (!password_verify($old_pwd, $xxxx_info['pwd'])) {
- // 用户名或密码错
- return;
- }
- }
- // 对密码长度、内容等不做限制。
- // 以应用场景来说,123456之类也无所谓。
- $pwd_in_db = password_hash($new_pwd, PASSWORD_DEFAULT, array("cost" => 6));
参考
https://www.php.net/manual/zh/faq.passwords.php#faq.passwords.fasthash
Tags: php用户密码进行加密技巧
- 上一篇:PHP中实现多语言支持的几种方式总结
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)