当前位置: 首页 > 后端技术 > PHP

如何加密用户密码

时间:2023-03-30 02:19:10 PHP

摘要密码验证是很常见的需求,如何在实现功能的同时防止用户密码泄露已经有非常成熟的解决方案。这篇文章记录了我的思考和结论。结语在对用户密码进行加密时,需要做到以下几点:防止用户密码明文被窃听1.交给https明文传输。2、客户端对密码加盐(盐是随机生成的,有强度),并进行哈希处理。服务器再次添加salt和hash并进行比较。假设https被窃听,攻击者破解密码明文是相当困难的。防止数据库被破坏时用户密码的明文被盗。1.增加哈希算法强度。2.随机生成有强度的盐。一些思想哈希算法是不可逆的。攻击者可以生成大量密码->哈希值键值对,反向映射,有概率通过哈希值获取密码。因此,破解成本=哈希算法强度×盐值个数。如何选择用户可接受的hash算法强度计算耗时(视应用场景而定,如0.2S以内)。计算时间越长越好,也就是增加哈希算法的强度。为什么盐应该是随机的?如果salt不是随机的,攻击者可以为单个salt生成hash值->password键值对,然后匹配整个数据库的hash值。假设盐是保密的,攻击者可以出于各种原因(代码泄漏、社会工程学等)获得盐。攻击者还可以通过哈希->攻击者密码+salt在数据库被破坏的站点上注册用户来破解salt。如果盐的强度(长度)不够,为什么盐要有强度。攻击者可以构建多个散列->密码数据库,以更高的概率匹配(破坏)一个简单的盐。为什么盐可以明文存储攻击者很难有足够的计算资源和存储空间来构建海量的哈希值->密码数据库。构建哈希值->密码数据库来攻击单个用户记录的成本太高。PHP实现的最初思路是房间密码。为了简单起见,我最初的想法是MD5+随机盐。在数据库中,大致是这样的:+--------+------------+------+-----+---------+------+|字段|类型|空|键|默认|额外|+--------+------------+------+------+--------+--------+|uid|整数(11)|否|优先级|空|||密码|变种(45)|是||空|||盐|变种(45)|是||空||+------+------------+------+-----+--------+------+php的推荐实现php的md5文档http://php.net/manual/zh/func...一个好的指南:http://php.net/manual/zh/faq....password_hash和crypt函数返回值的组成部分,顺序为:选择的算法、算法选项、使用的“salt”和散列密码。更改后数据库表变为:+--------+------------+------+-----+---------+------+|字段|类型|空|键|默认|额外|+--------+------------+------+------+--------+--------+|uid|整数(11)|否|优先级|空|||密码|变种(255)|是||空||+------+------------+------+-----+---------+------+与之前的方案相比:1.记录使用的算法(不改代码就可以升级算法)2.记录使用的算法的代价(强度),可以在硬件算力增加的时候,调整维护安全的成本。3.salt和hash值一起返回,简化了接口调用和数据库存储。PHP的认证接口设计得相当漂亮。使用方便,调用者强制使用随机盐(不易误用),可以在不修改代码的情况下扩展算法的强度。代码:if(!empty($xxxx_info['pwd'])){//如果有密码,需要校验if(!password_verify($old_pwd,$xxxx_info['pwd'])){//用户名或错误密码返回;}}//密码的长度和内容没有限制。//就应用场景而言,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...