public override async Task <bool> ValidateAsync(string purpose, string token, UserManager <AppUser> manager, AppUser user) { int code; if (!int.TryParse(token, out code)) { return(false); } List <UserTotpDevice> devices = await _authDbContext.UserTotpDevices .Where(u => u.User == user) .ToListAsync(); var unixTimestamp = Convert.ToInt64(Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds)); var timestep = Convert.ToInt64(unixTimestamp / 30); foreach (UserTotpDevice device in devices) { var hash = new HMACSHA1(Base32.FromBase32(device.SharedSecret)); for (int i = -2; i <= 2; i++) { var expectedCode = Rfc6238AuthenticationService.ComputeTotp(hash, (ulong)(timestep + i), modifier: null); if (expectedCode == code) { device.LastUsedTime = SystemClock.Instance.GetCurrentInstant(); await _authDbContext.SaveChangesAsync(); return(true); } } } return(false); }
public override async Task <bool> ValidateAsync(string purpose, string token, UserManager <AppUser> manager, AppUser user) { int code; if (!int.TryParse(token, out code)) { return(false); } List <string> keys = await _authDbContext.UserTotpDevices .AsNoTracking() .Where(u => u.User == user) .Select(t => t.SharedSecret) .ToListAsync(); var unixTimestamp = Convert.ToInt64(Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds)); var timestep = Convert.ToInt64(unixTimestamp / 30); foreach (string key in keys) { var hash = new HMACSHA1(Base32.FromBase32(key)); for (int i = -2; i <= 2; i++) { var expectedCode = Rfc6238AuthenticationService.ComputeTotp(hash, (ulong)(timestep + i), modifier: null); if (expectedCode == code) { return(true); } } } return(false); }
/// <summary> /// /// </summary> /// <param name="purpose"></param> /// <param name="token"></param> /// <param name="manager"></param> /// <param name="user"></param> /// <returns></returns> 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); }
public static string ComputeCode(string key) { 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); var topt = Rfc6238AuthenticationService.ComputeTotp(hash, (ulong)timestep, modifier: null); return(topt.ToString("D6", CultureInfo.InvariantCulture)); }
public static string ComputeCode(string key) { var keyBytes = Base32.FromBase32(key); var unixTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var timestep = Convert.ToInt64(unixTimestamp / 30); var topt = Rfc6238AuthenticationService.ComputeTotp(keyBytes, (ulong)timestep, modifier: null); return(topt.ToString("D6", CultureInfo.InvariantCulture)); }