密码哈希和验证

编辑本页

密码哈希和验证

大多数应用程序使用密码登录用户。这些密码应该被散列以安全地存储它们。ob娱乐下载Symfony的PasswordHasher组件提供了安全散列和验证密码的所有实用程序。

确保通过以下命令安装:

1
作曲家需要symfony/密码散列ob娱乐下载器

配置密码散列器

在对密码进行散列之前,必须使用password_hashers选择。您必须配置散列算法还有一些算法的选择

  • YAML
  • XML
  • PHP
  • 独立使用
12 3 4 5 6 7 8 9 10 11 12
#配置/包/ security.yaml安全:#……password_hashers:# User类(和子类)的默认选项的自动散列应用实体\ \用户:“汽车”为所有PasswordAuthenticatedUserInterface实例设置自定义选项ob娱乐下载Symfony \ \安全\ \用户\ PasswordAuthenticatedUserInterface核心组件:算法:“汽车”成本:15

在本例中,使用“auto”算法。这个散列器自动选择系统上可用的最安全的算法。结合迁移密码,这允许您始终以最安全的方式保护密码(即使在将来的PHP发行版中引入了新的算法)。

在本文的后面,您可以找到一个所有支持的算法的完整引用

提示

散列密码是资源密集型的,并且需要时间来生成安全的密码散列。一般来说,这使您的密码哈希更安全。

但是,在测试中,安全散列并不重要,因此可以在中更改密码散列配置测验更快地运行测试的环境:

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12
#配置/包/测试/ security.yamlpassword_hashers:使用你的用户类名应用实体\ \用户:算法:明文#禁用哈希(只在测试中这样做!)#或使用尽可能低的值应用实体\ \用户:算法:汽车这个值应该与config/packages/security.yaml中的值相同成本:4# bcrypt的最低可能值time_cost:3.#氩的最低可能值memory_cost:10#氩的最低可能值

哈希密码

配置正确的算法后,可以使用UserPasswordHasherInterface哈希和验证密码:

  • 框架的使用
  • 独立使用
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/ / src /控制器/ RegistrationController.php名称空间应用程序控制器/ /……使用ob娱乐下载组件HttpKernel异常AccessDeniedHttpException使用ob娱乐下载组件PasswordHasher切肉机UserPasswordHasherInterface用户控件扩展AbstractController公共函数登记(UserPasswordHasherInterfacepasswordHasher/ /……例如,从注册表单中获取用户数据用户用户(…);plaintextPassword=……;//哈希密码(基于安全。$user类的Yaml配置)hashedPasswordpasswordHasher->hashPassword (用户plaintextPassword);用户->向setPassword (hashedPassword);/ /……公共函数删除(UserPasswordHasherInterfacepasswordHasher,用户界面用户/ /……例如,从“确认删除”对话框中获取密码plaintextPassword=……;如果(!passwordHasher->isPasswordValid (用户plaintextPassword)) {AccessDeniedHttpException ();}}}

重置密码

使用MakerBundle而且ob娱乐下载SymfonyCastsResetPasswordBundle,您可以创建一个安全的开箱即用的解决方案来处理忘记密码。首先,安装SymfonyCastsReob娱乐下载setPasswordBundle:

1
Composer需要symfonyob娱乐下载casts/reset-password-bundle

然后,使用: reset-password命令。这会问你一些关于你的应用程序的问题,并生成你需要的所有文件!之后,您将看到一条成功消息和您需要执行的任何其他步骤的列表。

1
PHP bin/console make:重置密码

控件,可以自定义重置密码包的行为reset_password.yaml文件。有关配置的更多信息,请参阅ob娱乐下载SymfonyCastsResetPasswordBundle指南。

迁移密码

为了保护密码,建议使用最新的哈希算法存储密码。这意味着如果您的系统支持更好的散列算法,则用户的密码应该是重复。使用较新的算法和存储。这是可能的migrate_from选择:

  1. 使用“migrate_from”配置一个新的散列器
  2. 升级密码
  3. 可选地,从自定义散列触发密码迁移

使用“migrate_from”配置一个新的散列器

当有更好的散列算法可用时,您应该保留现有的散列器,重命名它,然后定义新的散列器。设置migrate_from新散列器上的选项指向旧的遗留散列器:

  • YAML
  • XML
  • PHP
  • 独立使用
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#配置/包/ security.yaml安全:#……password_hashers:#过去为某些用户使用的散列器遗留问题:算法:sha256encode_as_base64:迭代:1应用实体\ \用户:#新的散列器及其选项算法:migrate_from:-bcrypt#使用“bcrypt”散列器和默认选项-遗产#使用上面配置的“遗留”散列器

这样设置:

  • 新用户将使用新算法进行哈希;
  • 每当用户登录时,其密码仍然使用旧算法存储,Symfony将使用旧算法验证密码,然后使用新算法重新哈希并更新密码。ob娱乐下载

提示

汽车本地的bcrypt而且散列器使用以下列表自动启用密码迁移migrate_from算法:

  1. PBKDF2(它使用hash_pbkdf2);
  2. 消息摘要(使用哈希

两者都使用hash_algorithm设置为算法。建议使用migrate_from而不是hash_algorithm,除非汽车使用Hasher。

升级密码

在成功登录后,Security系统将检查是否有更好的算法可用于散列用户的密码。如果是,它将使用新的散列对正确的密码进行散列。在使用自定义身份验证器时,必须使用PasswordCredentials安全的护照

您可以通过实现这个新散列密码应该如何存储来启用升级行为:

在这之后,你就完成了,密码总是尽可能安全地散列!

请注意

在Symfony应用程序外部使用PasswordHasher组件时,必须手动使用ob娱乐下载PasswordHasherInterface: needsRehash ()方法检查是否需要重新散列PasswordHasherInterface: hash ()方法使用新算法重新散列明文密码。

使用Doctrine时升级密码

当使用实体用户提供商、实现PasswordUpgraderInterfaceUserRepository(见教义文档提供信息关于如何创建这个类(如果它还没有创建的话)。这个接口实现了存储新创建的密码哈希。

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src /仓库/ UserRepository.php名称空间应用程序存储库/ /……使用ob娱乐下载组件安全核心用户PasswordUpgraderInterfaceUserRepository扩展EntityRepository实现了PasswordUpgraderInterface/ /……公共函数upgradePassword(用户界面用户、字符串newHashedPassword无效//在User对象上设置新的散列密码用户->向setPassword (newHashedPassword);//在数据库上执行查询->getEntityManager ()->冲洗();}}

使用自定义用户提供程序时升级密码

如果你用的是定制用户提供程序,实现PasswordUpgraderInterface在用户提供程序中:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src /安全/ UserProvider.php名称空间应用程序安全/ /……使用ob娱乐下载组件安全核心用户PasswordUpgraderInterfaceUserProvider实现了UserProviderInterfacePasswordUpgraderInterface/ /……公共函数upgradePassword(用户界面用户、字符串newHashedPassword无效//在User对象上设置新的散列密码用户->向setPassword (newHashedPassword);/ /……保存新密码}}

从自定义散列触发密码迁移

如果使用自定义密码散列器,可以通过返回来触发密码迁移真正的needsRehash ()方法:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/ / src /安全/ CustomPasswordHasher.php名称空间应用程序安全/ /……使用ob娱乐下载组件PasswordHasher切肉机UserPasswordHasherInterfaceCustomPasswordHasher实现了UserPasswordHasherInterface/ /……公共函数needsRehash(字符串散列保龄球//检查当前密码是否使用过时的散列器hashIsOutdated=……;返回hashIsOutdated;}}

命名密码哈希器

通常,通过将密码散列器配置为应用于特定类的所有实例,可以对所有用户使用相同的密码散列器。另一种选择是使用“命名”散列器,然后选择您想动态使用的散列器。

默认情况下(如本文开头所示)汽车算法用于应用实体\ \用户

对于普通用户来说,这可能已经足够安全了,但如果您希望管理员拥有更强大的算法呢汽车成本更高。这可以通过命名哈希器来完成:

  • YAML
  • XML
  • PHP
  • 独立使用
1 2 3 4 5 6 7
#配置/包/ security.yaml安全:#……password_hashers:严厉的:算法:汽车成本:15

这将创建一个名为严厉的.为了得到a用户实例要使用它,类必须实现PasswordHasherAwareInterface.该接口只需要一个方法-getPasswordHasherName ()-返回要使用的散列器的名称:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/ / src /实体/ User.php名称空间应用程序实体使用ob娱乐下载组件PasswordHasher切肉机PasswordHasherAwareInterface使用ob娱乐下载组件安全核心用户PasswordAuthenticatedUserInterface使用ob娱乐下载组件安全核心用户用户界面用户实现了用户界面PasswordAuthenticatedUserInterfacePasswordHasherAwareInterface/ /……公共函数getPasswordHasherName():哦?字符串如果->isAdmin ()) {返回“苛刻”;}返回//使用默认散列器}}

如果您创建了自己的密码散列器,实现PasswordHasherInterface,你必须为它注册一个服务,以便使用它作为命名散列器:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6
#配置/包/ security.yaml安全:#……password_hashers:app_hasher:id:“Hasher App \安全\ \ MyCustomPasswordHasher”

这将创建一个名为app_hasher从具有ID的服务应用Hasher \安全\ \ MyCustomPasswordHasher

支持算法

“自动”散列器

它会自动选择最好的可用散列器(目前是Bcrypt)。如果PHP或Symfob娱乐下载ony将来添加新的密码散列器,它可能会选择不同的散列器。

因此,散列密码的长度将来可能会改变,因此请确保为它们分配足够的空间进行持久化(varchar (255)应该是个不错的设定)。

Bcrypt密码散列器

方法生成散列密码Bcrypt密码哈希功能.散列密码是60字符很长,所以请确保为它们分配足够的空间进行持久化。此外,密码还包括加密盐在它们里面(每个新密码都会自动生成),所以你不必处理它。

它唯一的配置选项是成本,取值范围为4-31(在默认情况下,13).每一个成本增量加倍的时间它需要对密码进行哈希。它是这样设计的,因此密码强度可以适应计算能力的未来改进。

您可以随时更改成本-即使您已经使用不同的成本散列了一些密码。新密码将使用新的代价进行哈希,而已经哈希的密码将使用哈希时使用的代价进行验证。

提示

使用BCrypt时,使测试更快的一个简单技术是将成本设置为4中允许的最小值测验环境配置。

钠密码散列器

它使用Argon2键推导函数.Argon2支持是在PHP 7.2中通过捆绑libsodium扩展。

散列后的密码为96字符长,但是由于保存在结果散列中的散列要求,这在将来可能会改变,所以请确保分配足够的空间来持久化它们。此外,密码还包括加密盐在它们里面(每个新密码都会自动生成),所以你不必处理它。

PBKDF2散列器

使用PBKDF2hasher不再推荐使用,因为PHP增加了对Sodium和BCrypt的支持。鼓励仍在使用它的遗留应用程序升级到那些更新的哈希算法。

创建自定义密码散列器

如果你需要创建自己的,它需要遵循以下规则:

  1. 类必须实现PasswordHasherInterface(您也可以实现LegacyPasswordHasherInterface如果你的哈希算法使用一个单独的盐);
  2. 的实现hash ()而且验证()必须验证密码长度不超过4096个字符。这是出于安全原因(参见cve - 2013 - 5750).

    您可以使用isPasswordTooLong ()方法。

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / src /安全/厨师/ CustomVerySecureHasher.php名称空间应用程序安全切肉机使用ob娱乐下载组件PasswordHasher异常InvalidPasswordException使用ob娱乐下载组件PasswordHasher切肉机CheckPasswordLengthTrait使用ob娱乐下载组件PasswordHasherPasswordHasherInterfaceCustomVerySecureHasher实现了PasswordHasherInterface使用CheckPasswordLengthTrait公共函数哈希(字符串plainPassword字符串如果->isPasswordTooLong (plainPassword)) {InvalidPasswordException ();}/ /……以安全的方式哈希普通密码返回hashedPassword;}公共函数验证(字符串hashedPassword、字符串plainPassword保龄球如果= = =plainPassword||->isPasswordTooLong (plainPassword)) {返回;}/ /……以安全的方式验证密码是否等于用户密码返回passwordIsValid;}}

方法定义密码散列器id设置:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7
#配置/包/ security.yaml安全:#……password_hashers:app_hasher:#你的自定义散列器的服务ID(使用默认services.yaml的FQCN)id:“Hasher App \安全\ \ MyCustomPasswordHasher”
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 6.2支持通过苏禄人
ob娱乐下载Symfony 6.2支持通过Les-Tilleuls.coop