PBKDF2适合登录密码验证吗?

Posted

技术标签:

【中文标题】PBKDF2适合登录密码验证吗?【英文标题】:Is PBKDF2 suitable for login password verification? 【发布时间】:2021-10-25 17:24:07 【问题描述】:

据我所知,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

请为您的答案找到一个好的来源,而不是只写“是的”。 如果是,存储的哈希的足够长度是多少?该长度是如何确定的?

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

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

以上是关于PBKDF2适合登录密码验证吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中使用 PBKDF2 进行密码验证

01 | 你真的懂测试吗?从“用户登录”测试谈起 茹炳晟

网站后台登录

使用登录名和密码或证书进行身份验证

使用Pbkdf2加密加密和验证使用Salt的哈希密码

Win10登录框如何去掉“小眼睛”