VerifyHashedPassword 结果什么时候会是 SuccessRehashNeeded

When will VerifyHashedPassword result be SuccessRehashNeeded

Usermanager.VerifyHashedPassword的结果什么时候变成PasswordVerificationResult.SuccessRehashNeeded

出现这样的结果怎么办?

当使用 VerifyHashedPassword 时,我只用 Success 检查它。够了还是我应该用 Failed 检查一下?

我在 PasswordHasher.cs in github

的来源中找到了这个
public virtual PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword)
        {
            if (hashedPassword == null)
            {
                throw new ArgumentNullException(nameof(hashedPassword));
            }
            if (providedPassword == null)
            {
                throw new ArgumentNullException(nameof(providedPassword));
            }

            byte[] decodedHashedPassword = Convert.FromBase64String(hashedPassword);

            // read the format marker from the hashed password
            if (decodedHashedPassword.Length == 0)
            {
                return PasswordVerificationResult.Failed;
            }
            switch (decodedHashedPassword[0])
            {
                case 0x00:
                    if (VerifyHashedPasswordV2(decodedHashedPassword, providedPassword))
                    {
                        // This is an old password hash format - the caller needs to rehash if we're not running in an older compat mode.
                        return (_compatibilityMode == PasswordHasherCompatibilityMode.IdentityV3)
                            ? PasswordVerificationResult.SuccessRehashNeeded
                            : PasswordVerificationResult.Success;
                    }
                    else
                    {
                        return PasswordVerificationResult.Failed;
                    }

                case 0x01:
                    int embeddedIterCount;
                    if (VerifyHashedPasswordV3(decodedHashedPassword, providedPassword, out embeddedIterCount))
                    {
                        // If this hasher was configured with a higher iteration count, change the entry now.
                        return (embeddedIterCount < _iterCount)
                            ? PasswordVerificationResult.SuccessRehashNeeded
                            : PasswordVerificationResult.Success;
                    }
                    else
                    {
                        return PasswordVerificationResult.Failed;
                    }

                default:
                    return PasswordVerificationResult.Failed; // unknown format marker
            }
        }

似乎 SuccessRehashNeeded 是我们从当前 Identity 版本更改为另一个版本时的结果。

要添加到现有答案,PasswordVerificationResult.SuccessRehashNeeded 还可能表示散列函数的参数(例如 work factor)已更改,密码需要重新散列以生成使用新参数进行散列。由于应用程序访问用户密码的唯一时间是在哈希验证期间,这是应用程序唯一能够重新哈希用户密码的时间,这就是为什么这是结果的一个选项。

这确实是我们在 PasswordHasher.cs 中看到的。 IPasswordHasher 是 "upgrading" 哈希,通过将其标记为使用新参数重新哈希。

SuccessRehashNeeded 是一种很好的方法,可以在用户访问其帐户时将现有用户密码哈希静默迁移到新算法。

例如,Microsoft 将其用作从 Sql 成员身份迁移到 Microsoft Identity 的开发人员的迁移指南的一部分。现有密码仍可用于登录,但应在发生这种情况后立即重新哈希。

查看 https://docs.microsoft.com/en-us/aspnet/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity 示例(在页面中搜索 SuccessRehashNeeded)。