When will VerifyHashedPassword result be SuccessRehashNeeded
Asked Answered
A

3

9

When will the result of Usermanager.VerifyHashedPassword result be PasswordVerificationResult.SuccessRehashNeeded ?

What to do if such result occur?

When using VerifyHashedPassword i only check it with Success. Is it enough or should i check it with Failed?

Acariasis answered 15/5, 2015 at 5:13 Comment(0)
A
8

i found this in source of 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
            }
        }

Seems like SuccessRehashNeeded is the result when we change from current Identity version to another.

Acariasis answered 15/5, 2015 at 7:26 Comment(0)
V
7

SuccessRehashNeeded is a good way to silently migrate existing user password hashes to a new algorithm any time those users access their accounts.

For example, Microsoft uses it as part of their migration guide for developers who are moving from Sql Membership to Microsoft Identity. Existing passwords can still be used to login, but should be rehashed as soon as this occurs.

See https://learn.microsoft.com/en-us/aspnet/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity for an example (search the page for SuccessRehashNeeded).

Vezza answered 29/11, 2018 at 20:55 Comment(4)
Note: you must implement the logic to react to SuccessRehashNeeded and do the migration yourself. See: stackoverflow.com/a/44098541Septuagesima
Johann is correct. I'll note that Asp.Net Core Identity does the migration for you.Vezza
Is it possible to prevent this behaviour? As in, do not silently migrate existing user password hashes?Montgolfier
@FernandoGómez: You could override the password hasher to not return SuccessRehashNeeded. In the specific case that you're trying to maintain legacy compatibility between IdentityV2 (.Net Framework) and IdentityV3 applications, add services.Configure<PasswordHasherOptions>(o => o.CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV2); to the ConfigureServices startup method of your IdentityV3 applications.Vezza
S
1

To add to the existing answer(s), PasswordVerificationResult.SuccessRehashNeeded may also indicate that a parameter of the hash function (eg. the work factor) has changed and the password needs rehashing to generate a hash with the new parameters. As the only time the application has access to a user's password is during hash verification, this is the only time the application will be able to rehash a user's password and is why this is an option for the result.

This is, indeed, what we see in PasswordHasher.cs. The IPasswordHasher is "upgrading" the hash by flagging it for rehashing with the new parameters.

Scraggly answered 3/11, 2016 at 5:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.