站长资讯网
最全最丰富的资讯网站

PHP开发者如何做好密码保护以及Laravel底层密码存储和验证实现

随着在线攻击的增多,密码安全越来越重要。作为开发者我们要担负起安全管理、计算哈希和存储用户密码的责任,不管应用是简单的游戏还是绝密商业文件的仓库,都要做到这一点。PHP内置了一些工具,让保护密码变得更加容易,本节我们就来讨论如何根据现代的安全措施来使用这些工具。

1、密码保护三原则

绝对不能知道用户的密码

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

绝对不要约束用户的密码

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

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

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

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

2、密码存储算法

关于密码存储的最佳实践是计算密码的哈希值,而不是加密用户的密码。加密和哈希不是一回事,加密事双向算法,加密的数据可以解密,而哈希是单向算法,哈希后的数据不能再还原成原始值,而且相同的数据得到的哈希值始终相同。

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

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

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

3、密码哈希API

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

开发Web应用时,有两个地方会用到密码哈希API:注册用户和用户登录,下面我们以Laravel提供的用户注册和登录为例,看看PHP密码哈希API时如何简化这两个操作的。

注:Laraval框架内置的用户注册和登录功能正是使用了PHP哈希API实现密码的存储和验证。

注册用户

用户注册在AuthController中完成,新用户的创建在该控制器的create方法中实现:

PHP开发者如何做好密码保护以及Laravel底层密码存储和验证实现

可以看到这里使用了Laravel提供的辅助函数bcrypt对用户提交的密码进行哈希并保存到数据库。bcrypt函数定义如下:

PHP开发者如何做好密码保护以及Laravel底层密码存储和验证实现

这里我们可以看出实际上是调用了别名为hash的服务提供者实例上的make方法实现哈希密码,进入HashServiceProvider,在register方法中我们可以看到hash对应的类为BcryptHasher,在该类中我们找到了make方法:

PHP开发者如何做好密码保护以及Laravel底层密码存储和验证实现

这里的核心是调用了PHP提供的password_hash函数,该函数接收三个参数,第一个是用户输入的密码值,第二个参数是使用的哈希算法(

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号