stella-maris/nist-password

根据NIST处理密码

dev-main 2024-04-13 07:26 UTC

This package is not auto-updated.

Last update: 2024-09-14 09:22:39 UTC


README

一个用于以NIST合规方式使用密码的库。

该库实现了NIST特别出版物800-63B中提到的所有相关要点,详见第5.1.1节

codecov

为什么?

NIST向美国的国家机构提供建议,包括数字问题。其中之一是身份验证和授权。因此,本质上NIST向国家机构如NSA提供建议(包括其他事项),关于什么构成了安全的密码和什么构成了安全的认证机制。

这个库将这些书面规则转换为你可以在代码中使用的库。但代码并非一切,NIST的建议还需要应用于你的流程。更多内容请参考流程章节。

如何?

通过composer要求库

$ composer require stella-maris/nist-password

现在你可以使用以下代码来验证密码是否符合NIST规则,如下所示:

use StellaMaris\NistPassword\Validate;
use StellaMaris\Password\Filters\FilterListFactory;
use StellaMaris\Password\Validate\ValidatorListFactory;

$validator = new Validate(
    ValidatorListFactory::create(),
	FilterListFactory::create(),
);
$feedback = $validator->validate($password);
if (! $feedback->isValid()) {
	var_Dump($feedback->getViolations());
}

getViolations()方法将返回一个包含Violation对象的列表,然后可以查询这些对象以获取更多信息。

一旦验证了新密码是有效的,你可以像这样从验证器中获取密码散列进行存储

$password = $feedback->getPassword();

echo $password;

密码存储在一个相当安全地防止意外泄露明文密码的对象中。

为此,Password对象使用预定义的盐和脚本运行结束时丢弃的密码以对称加密方式存储明文密码。将对象转换为字符串将仅显示散列密码。密码散列使用PHP的密码散列库创建。

如果你出于任何原因需要再次以明文形式使用密码,可以通过yesIDoNeedThePasswordInCleartextAndIKnowOfTheImplicationsThatMightHave()方法获取访问权限。警告:此方法的返回值将再次暴露明文密码!你应该尽快使用它,并立即销毁变量,如下所示

$password = $feedback->getPassword();

// No intermediary variable!
ldap_bind($ldap_connection, $user, $password->yesIDoNeedThePasswordInCleartextAndIKnowOfTheImplicationsThatMightHave());

// immediately unset the variable after usage!
$pass = $password->yesIDoNeedThePasswordInCleartextAndIKnowOfTheImplicationsThatMightHave();
ldap_bind($ldap_connection, $user, $pass);
unset($pass);

然后你可以使用此过程进行实际的身份验证:

use StellaMaris\NistPasword\Authenticator;

$authenticator = new Authenticator();
$result = $authenticator->authenticate($password, $hashFromDatabase);
if (! $result->isValid()) {
	echo "The login credentials are invalid"
}

if ($result->isRehashed()) {
	// The existing credentials are not considered strong enough any more so the
	// password has been rehasehd with a stronger algorithm and now needs to be
	// persisted again
	$pdo->query(`UPDATE users SET password=:password WHERE user = :user`, [
		'password' => (string) $result->getPassword(),
		'user' => $user,
	]);
}

if ($needsNewPassword) {
    // The whole password set has been compromized so the users have to create a new
    // password at login.
    // You should implement this logic right from the start, hoping that you will never need it
    // Make sure that you can somehow verify that a user is actually the user they claim to be
    // by using some verification mechanism (like sending an email to their registered address)
    // Think about that the emails might have been compromized. Make sure that you detect
    // unwanted tampering with that data!
    // Do NOT - I repeat: NOT! - use "security questions". Those are considered bad practice
}

如果你需要为用户生成一个新的密码,可以像这样创建一个:

use StellaMaris\NistPassword\PasswordCreator;

$password = new PasswordCreator();

echo sprintf(
    "The password for %s is %s",
    $user,
    $password->yesIDoNeedThePasswordInCleartextAndIKnowOfTheImplicationsThatMightHave()
);

$pdo->query(`UPDATE users SET password=:password WHERE user = :user`, [
		'password' => (string) $result->getPassword(),
		'user' => $user,
	]);

流程

你可能需要调整你的流程以符合NIST标准。

一般要求

根据认证者保证级别,你将需要除了这里提到的记忆密码之外的其他因素。请查阅您的需求文档

此包仅负责记忆密码!

密码恢复

你不应该使用安全问题来恢复对已锁定账户的访问!