资讯专栏INFORMATION COLUMN

如何对用户密码进行加密

张率功 / 2392人阅读

摘要:结论对用户密码进行加密时需要做到防止用户密码明文被窃听交给,明文传输。为什么盐可以明文存储攻击者很难有足够的计算资源和存储空间建立海量的哈希值密码数据库,针对单条用户记录,建立哈希值密码数据库进行攻击的成本过高。

摘要

密码验证是很常见的需求,如何在实现功能之余,防止用户密码泄露,已经有了很成熟的方案。这篇文章把自己的思考和结论做一下记录。

结论

对用户密码进行加密时需要做到:

防止用户密码明文被窃听

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文档
http://php.net/manual/zh/func...
给了一个很好的指引:
http://php.net/manual/zh/faq....

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 (!empty($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));  
参考

http://php.net/manual/zh/faq....
http://www.infoq.com/cn/artic...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26233.html

相关文章

  • 当我们在谈论前端加密时,我们在谈些什么

    摘要:所以我们今天只谈前端加密,一个部分人认为没有意义的工作。在中,认证过程使用了非对称加密算法,非认证过程中使用了对称加密算法。非对称加密上文中我们讨论了前端的哈希加密以及应用的场景。 showImg(https://segmentfault.com/img/bVAhTC); 当然在谈安全。 前端安全是Web安全的一部分,常见的安全问题会有XSS、CSRF、SQL注入等,然而这些已经在程师...

    wizChen 评论0 收藏0
  • FineReport中如何cpt模板加密

    摘要:描述客户使用报表并将其集成到自己的产品中,然后提供给最终用户使用,最终用户可以预览模板,但是不能打开模板进行设计修改。点击确定即可,然后就会对该工程下的所有模板进行加密。注加密只能对工程下所有模板加密,不能单独加密。 1.描述FR客户使用FineReport报表并将其集成到自己的产品中,然后提供给最终用户使用,最终用户可以预览FR模板,但是不能打开模板进行设计修改。FineReport...

    waruqi 评论0 收藏0
  • 区块链学习之密码学安全技术(五)

    摘要:非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解离散对数椭圆曲线等经典数学难题进行保护。消息认证码基于对称加密,可以用于对消息完整性进行保护。 Hash 算法与数字摘要 Hash (哈希或散列)算法它能将任意长度的二进制明文串映射为较短的(通常是固定长度的)二进制串(Hash值),并且不同的明文很难映射为相同的Hash值。 Hash 定义 Hash (哈希...

    aboutU 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<