public async Task <IActionResult> SetupTotp() { ApplicationUser user = await _userManager.GetUserAsync(User); if (!user.TotpEnabled) { byte[] keyBytes; if (user.TotpSecret != null) { keyBytes = user.TotpSecret; } else { keyBytes = KeyGeneration.GenerateRandomKey(20); } string base32Key = Base32Encoding.ToString(keyBytes); byte[] base32KeyBytes = Base32Encoding.ToBytes(base32Key); Totp totp = new Totp(base32KeyBytes); user.TotpSecret = keyBytes; await _userManager.UpdateAsync(user); QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode($"otpauth://totp/SPSAuthChallenge:{user.UserName}?secret={base32Key}&issuer=SPSAuthChallenge", QRCodeGenerator.ECCLevel.Q); Base64QRCode qrCode = new Base64QRCode(qrCodeData); string qrCodeBase64 = qrCode.GetGraphic(10); SetupTotpViewModel model = new SetupTotpViewModel { QRCodeBase64 = qrCodeBase64 }; return(View(model)); } return(RedirectToAction(nameof(Index))); }
public async Task <IActionResult> SetupTotp(SetupTotpViewModel model) { if (ModelState.IsValid) { ApplicationUser user = await _userManager.GetUserAsync(User); if (!user.TotpEnabled) { string password = model.ConfirmPasswordAndPIN.Substring(0, model.ConfirmPasswordAndPIN.Length - 6); string pin = model.ConfirmPasswordAndPIN.Substring(model.ConfirmPasswordAndPIN.Length - 6); Totp totp = new Totp(user.TotpSecret); if (totp.VerifyTotp(pin, out long window, VerificationWindow.RfcSpecifiedNetworkDelay)) { if (await _userManager.CheckPasswordAsync(user, password)) { user.TotpEnabled = true; await _userManager.UpdateAsync(user); StatusMessage = "One-time Token Set Up!"; return(RedirectToAction(nameof(Index))); } } } else { return(RedirectToAction(nameof(Index))); } } return(RedirectToAction(nameof(SetupTotp))); }