PBKDF2是否适用于登录密码验证?

Is PBKDF2 suitable for login password verification?

据我所知,PBKDF2 旨在用于从可变长度密码创建所需大小的密钥,以按以下方式(伪代码)用于对称加密:

//Encrypt
var Password = GetSomeUserInput();
var DataToEncrypt = GetSomeUserInput();

var Salt = CreateACryptographicallyStrongRandomSalt(sufficient length);
var DF = new Pbkdf2(Password, Salt, Iterations := sufficient iterations);
var Key = DF.MunchBytes(256); //AES256 key   size is 256
var IV  = DF.MunchBytes(128); //AES256 block size is 128

var EncryptedData = EncryptWithAes256(DataToEncrypt, Key, IV);
StoreData(Salt, EncryptedData);

//Decrypt
var Password = GetSomeUserInput();

var Salt, EncryptedData = RestoreData();
var DF = new Pbkdf2(Password, Salt, Iterations := sufficient iterations);
var Key = DF.MunchBytes(256);
var IV  = DF.MunchBytes(128);

var DecryptedData = DecryptWithAes256(EncryptedData, Key, IV);

PBKDF2也适合这样的密码验证吗? (伪代码):

//Registration
var UserName = GetSomeUserInput();
var Password = GetSomeUserInput();

var Salt = CreateACryptographicallyStrongRandomSalt(sufficient length);
var DF = new Pbkdf2(Password, Salt, Iterations := sufficient iterations);
var Hash = DF.MunchBytes(sufficient length);

StoreData(UserName, Salt, Hash);

//Login
var UserName = GetSomeUserInput();
var Password = GetSomeUserInput();

var Salt, StoredHash = RestoreByUserName(UserName)
var DF = new Pbkdf2(Password, Salt, Iterations := sufficient iterations);
var RecomputedHash = DF.MunchBytes(sufficient length);

if (ConstantTimeEquals(StoredHash, RecomputedHash))
{
  //OK
}

请找到一个好的答案来源,而不是只写“是的。”
如果是,the/a 存储散列的足够长度是多少?该长度是如何确定的?

理想情况下,以下内容不会对答案产生影响,但如果您需要更多上下文:
这是一个 运行-of-the-mill 浏览器->json->jetty->jdbc->mariadb 网站,我希望用户能够在其中注册一个帐户然后登录使用该帐户。 Jetty 是 Java(因此是标签),但同样适用于例如.NET 和其他 languages/frameworks。

是的,NIST uses PBKDF2 as an example 一种适合用于密码身份验证系统的单向散列。为此,通常建议使用安全密钥派生函数。

然而,PBKDF2 的潜在改进已经得到认可,促使开发了一系列算法,例如 bcrypt, Scrypt, and Argon2. 这些算法旨在抵抗硬件优化。因此,虽然 PBKDF2 在许多情况下可能就足够了,但可能还需要额外的安全性。

在实践中,我觉得最大的风险是使用错误的密码,其次是使用太小的工作因素。首先,使用 Have I Been Pwned database. 之类的东西拒绝密码。其次,大胆思考:PBKDF2 的数十万甚至 100k 次迭代。您还可以考虑设计您的身份验证数据库以允许逐步迁移到新算法(在用户登录时透明),以防您将来想要更改哈希算法。