Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When will VerifyHashedPassword result be SuccessRehashNeeded

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?

like image 916
Ruchan Avatar asked May 15 '15 05:05

Ruchan


2 Answers

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.

like image 101
Ruchan Avatar answered Sep 21 '22 21:09

Ruchan


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://docs.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).

like image 28
Brian Avatar answered Sep 18 '22 21:09

Brian