【最佳实践系列】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 方法中实现:
可以看到这里使用了Laravel提供的辅助函数 bcrypt 对用户提交的密码进行哈希并保存到数据库。 bcrypt 函数定义如下:
这里我们可以看出实际上是调用了别名为 hash 的服务提供者实例上的 make 方法实现哈希密码,进入 HashServiceProvider ,在 register 方法中我们可以看到 hash 对应的类为 BcryptHasher ,在该类中我们找到了 make 方法:
这里的核心是调用了PHP提供的 password_hash 函数,该函数接收三个参数,第一个是用户输入的密码值,第二个参数是使用的哈希算法(更多算法查看: http://php.net/manual/zh/password.constants.php ),第三个参数可选,包括 salt 和 cost 两个选项,分别表示干扰字符串(加盐)和前面提到的工作因子,工作因子可以随着硬件性能的提升而提升,不传的话使用随机加盐和默认工作因子(计算哈希值一般需要0.1~0.5s)。如果计算失败,抛出异常。
用户登录
在Larval中以在 auth.php 中使用session作为guards、eloquent作为providers实现用户登录认证为例(实际上默认设置就是这样),登录验证最终会走到 EloquentUserProvider 的 validateCredentials 方法:
$this->hasher 对应的实现也是 BcryptHasher 类,我们来查看它的 check 方法:
其中传入的第一个参数是用户输入的密码,第二个参数是用户注册时保存的密码哈希值,如果哈希值为空直接返回false,否则调用php提供的 password_verify 函数,该函数用于验证密码(纯文本)和哈希值是否匹配,匹配返回true,否则返回false。
重新计算哈希值
通过上述步骤用户已经可以实现登录认证了,但是登录前我们还需要检查现有的密码哈希值是否已经过期,如果过期,需要重新计算密码哈希值。
为什么要重新计算呢?加入我们的应用创建于两年前,那时候使用的工作因子时10,现在使用的是20,因为计算机的速度更快了,黑客也更聪明了。可以有些用户的密码哈希值仍然是工作因子为10时生成的,这时,登录认证通过后,要使用 password_needs_refresh 函数检查用户记录中现有的哈希值是否需要更新,这个函数可以确保指定的密码哈希值是使用最新的哈希算法创建的。如果确实需要重新计算生成密码的哈希值,要使用 make 方法生成新的哈希值并更新数据库中的原密码。
Laraval中目前并没有使用这一功能,但是在 BcryptHasher 类中已经提供了对应的函数:

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP에는 4 가지 주요 오류 유형이 있습니다. 1. NOTICE : 가장 작은 것은 정의되지 않은 변수에 액세스하는 것과 같이 프로그램을 방해하지 않습니다. 2. 경고 : 심각한 통지는 파일을 포함하지 않는 것과 같은 프로그램을 종료하지 않습니다. 3. FatalError : 가장 심각한 것은 기능을 부르는 것과 같은 프로그램을 종료합니다. 4. parseerror : 구문 오류는 엔드 태그를 추가하는 것을 잊어 버리는 것과 같이 프로그램이 실행되는 것을 방지합니다.

PHP에서 Password_hash 및 Password_Verify 기능을 사용하여 보안 비밀번호 해싱을 구현해야하며 MD5 또는 SHA1을 사용해서는 안됩니다. 1) Password_hash는 보안을 향상시키기 위해 소금 값이 포함 된 해시를 생성합니다. 2) Password_verify 암호를 확인하고 해시 값을 비교하여 보안을 보장합니다. 3) MD5 및 SHA1은 취약하고 소금 값이 부족하며 현대 암호 보안에는 적합하지 않습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP는 전자 상거래, 컨텐츠 관리 시스템 및 API 개발에 널리 사용됩니다. 1) 전자 상거래 : 쇼핑 카트 기능 및 지불 처리에 사용됩니다. 2) 컨텐츠 관리 시스템 : 동적 컨텐츠 생성 및 사용자 관리에 사용됩니다. 3) API 개발 : 편안한 API 개발 및 API 보안에 사용됩니다. 성능 최적화 및 모범 사례를 통해 PHP 애플리케이션의 효율성과 유지 보수 성이 향상됩니다.

HTTP 요청 방법에는 각각 리소스를 확보, 제출, 업데이트 및 삭제하는 데 사용되는 Get, Post, Put and Delete가 포함됩니다. 1. GET 방법은 리소스를 얻는 데 사용되며 읽기 작업에 적합합니다. 2. 게시물은 데이터를 제출하는 데 사용되며 종종 새로운 리소스를 만드는 데 사용됩니다. 3. PUT 방법은 리소스를 업데이트하는 데 사용되며 완전한 업데이트에 적합합니다. 4. 삭제 방법은 자원을 삭제하는 데 사용되며 삭제 작업에 적합합니다.

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

phpoop에서 self ::는 현재 클래스를 말하며, Parent ::는 부모 클래스를 말하며, static ::는 늦은 static 바인딩에 사용됩니다. 1. self :: 정적 방법과 일정한 호출에 사용되지만 늦은 정적 바인딩을 지원하지는 않습니다. 2.parent :: 하위 클래스가 상위 클래스 방법을 호출하는 데 사용되며 개인 방법에 액세스 할 수 없습니다. 3. Static ::는 상속 및 다형성에 적합한 후기 정적 결합을 지원하지만 코드의 가독성에 영향을 줄 수 있습니다.

PHP는 $ \ _ 파일 변수를 통해 파일 업로드를 처리합니다. 보안을 보장하는 방법에는 다음이 포함됩니다. 1. 오류 확인 확인, 2. 파일 유형 및 크기 확인, 3 파일 덮어 쓰기 방지, 4. 파일을 영구 저장소 위치로 이동하십시오.
