PHP开发建议 第2章 密码保护 PHP开发建议 第2章 密码保护

2023-02-12

随着在线攻击的增多,密码安全越来越重要。作为开发者我们要担负起安全管理、计算哈希和存储用户密码的责任,不管应用是简单的游戏还是绝密商业文件的仓库,都要做到这一点。

PHP 内置了一些工具,让保护密码变得更加容易,本节我们就来讨论如何根据现代的安全措施来使用这些工具。

一、密码保护三原则

1.1、绝对不能知道用户的密码

我们绝对不能知道用户的密码,也不能有获取用户密码的方式,如果应用的数据库被黑,你肯定不希望数据库中有纯文本或能解密的密码。任何时候,知道的越少越安全。

1.2、绝对不要约束用户的密码

如果要求密码符合特定的模式,其实是为不怀好意的人提供了攻击应用的途径,如果必须约束密码,我建议只限制最小长度,把常用的密码或基于字典创建的密码加入黑名单也是好主意。

1.3、绝对不能通过电子邮件发送用户密码

如果你通过电子邮件给用户发送密码,用户会知道三件事:你知道他的密码,你使用纯文本或能解密的方式存储了他的密码,你没有对通过互联网发送纯文本的密码感到不安。

我们应该在电子邮件中发送用于设置或修改密码的 URL,Web 应用通常会生成一个唯一的令牌,这个令牌只在设定或修改密码时使用一次(比如修改密码),通常我们把这个令牌作为设置或修改密码 URL 的一个参数,当用户访问这个 URL 时,应用会验证令牌是否有效,如果有效则继续操作,操作完成后,令牌失效,不能重复使用。

二、密码存储算法

关于密码存储的最佳实践是计算密码的哈希值,而不是加密用户的密码。

加密和哈希不是一回事,加密事双向算法,加密的数据可以解密,而哈希是单向算法,哈希后的数据不能再还原成原始值,而且相同的数据得到的哈希值始终相同。

在数据库中存储用户的密码,要先计算密码的哈希值,然后在数据库中存储密码的哈希值,如果黑客攻入数据库,只能看到无意义的密码哈希值,需要花费大量的时间和 NSA 资源才能破解。

哈希算法有很多种(如md5、SHA1、bcrypt和scrypt),有些算法速度很快,用于验证数据完整性;有些算法的速度则很慢,旨在提高安全性。生成密码和存储密码时要使用速度慢、安全性高的算法。

目前,最安全的算法当属 bcrypt,与 md5 和 SHA1 不同,bcrypt 故意设计得很慢,bcrypt 会自动加盐(salt),防止潜在的彩虹表攻击,bcrypt 算法会花费大量时间反复处理数据,生成特别安全的哈希值。在这个过程中,处理数据的次数叫工作因子,工作因子的值越高,破解密码所需的时间越长,安全性越好。bcrypt 算法永不过时,如果计算机运算速度变快了,我们只需提高工作因子的值。

三、密码哈希API

通过前面的介绍,我们知道在处理用户的密码时要考虑很多东西,好在PHP 5.5.0 原生的哈希API(http://php.net/manual/zh/book.password.php)提供了很多易于使用的函数,大大简化了计算密码哈希值和验证密码的操作,而且,这个密码哈希  API 默认使用bcrpt 算法。

开发 Web 应用时,有两个地方会用到密码哈希 API:注册用户和用户登录。

password_hash

该函数接收三个参数,第一个是用户输入的密码值,第二个参数是使用的哈希算法(更多算法查看:http://php.net/manual/zh/password.constants.php),第三个参数可选,包括  salt 和 cost 两个选项,分别表示干扰字符串(加盐)和前面提到的工作因子,工作因子可以随着硬件性能的提升而提升,不传的话使用随机加盐和默认工作因子(计算哈希值一般需要0.1~0.5s)。

password_verify

该函数用于验证密码(纯文本)和哈希值是否匹配。

password_needs_refresh

该函数用于检查用户记录中现有的哈希值是否需要更新。

通过上述步骤用户已经可以实现登录认证了,但是登录前我们还需要检查现有的密码哈希值是否已经过期,如果过期,需要重新计算密码哈希值。

为什么要重新计算呢?比如我们的应用创建得时候使用的工作因子是 10,现在使用的是 20,因为计算机的速度更快了,黑客也更聪明了。

可以有些用户的密码哈希值仍然是工作因子为 10 时生成的,这时,登录认证通过后,要使用 password_needs_refresh 函数检查用户记录中现有的哈希值是否需要更新,这个函数可以确保指定的密码哈希值是使用最新的哈希算法创建的。

如果确实需要重新计算生成密码的哈希值,要使用 password_hash 方法生成新的哈希值并更新数据库中的原密码。

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开微信扫一扫,即可进行扫码打赏哦

阅读 326