Microsoft Identity better use of AuthenticatorTokenProvider?

545 views Asked by At

I've recently come across the below Microsoft.Identity class that can be used as a way to provide 2FA generation and validation to users that are logging in, acting as a second factor protection. I wanted to know if anyone has found a better class or library or code practice that can be used than the below example?

https://github.com/aspnet/Identity/blob/master/src/Core/AuthenticatorTokenProvider.cs

Code especially in question:

public virtual async Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user)
    {
        var key = await manager.GetAuthenticatorKeyAsync(user);
        int code;
        if (!int.TryParse(token, out code))
        {
            return false;
        }

        var hash = new HMACSHA1(Base32.FromBase32(key));
        var unixTimestamp = Convert.ToInt64(Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds));
        var timestep = Convert.ToInt64(unixTimestamp / 30);
        // Allow codes from 90s in each direction (we could make this configurable?)
        for (int i = -2; i <= 2; i++)
        {
            var expectedCode = Rfc6238AuthenticationService.ComputeTotp(hash, (ulong)(timestep + i), modifier: null);
            if (expectedCode == code)
            {
                return true;
            }
        }
        return false;
    }

Reason I'm not comfortable with the above script is because this code (as far as I have tested) is not One-Time-Use, and the set up allows the user to enter older codes (up to 89 secs in this example), and if you changed the i variable to 0 in this case, that means the code is only valid within the 30s timestep.

the timestep variable (in this case) is updated every 30 seconds in real time. so at 12:01:40 you could have been sent a code to validate, but that could is not "valid" for 30 seconds, it's only valid for 19 seconds until the next 30 second timestep update.

You could argue to increase the timestep length to 3 minutes but regardless it still poses the potential for a user to request a code right before that next timestep update.

1

There are 1 answers

0
Stuart On

Through some digging done, Microsoft brought this 'TOTP' 2fa method which uses Time as it's way of generating these codes, as well as other modifiers like your securitystamp and hashing.

Solution I found was to keep this implementation but Update the users SecurityStamp once they successsfully validate, this also means the sign-in cookie must be refreshed. (because sign-in cookie uses SecurityStamp to generate, and is validated the same way)

Preferable I would stray away from this implementation and rather use a more robust standard (Proper OTP), but this solution works and is still a valid security method.