public Totp(string base32Secret) { byte[] secretBytes = Base32.ToByteArray(base32Secret); DateTime utcNow = DateTime.UtcNow; long unixNow = ToUnixTime(utcNow); long timestamp = Convert.ToInt64(unixNow / FREQUENCY_SECONDS); byte[] timestampBytes = BitConverter.GetBytes(timestamp).ToArray(); // IBM PC architecture is little endian Array.Reverse(timestampBytes); using (HMACSHA1 hmac = new HMACSHA1(secretBytes)) { byte[] hmacBytes = hmac.ComputeHash(timestampBytes); int offset = hmacBytes.Last() & 0x0F; int firstByte = (hmacBytes[offset + 0] & 0x7F) << 24; int secondByte = hmacBytes[offset + 1] << 16; int thirdByte = hmacBytes[offset + 2] << 8; int fourthByte = hmacBytes[offset + 3]; int authenticationCode = (firstByte | secondByte | thirdByte | fourthByte) % 1000000; // pad with leading zeroes AuthenticationCode = authenticationCode.ToString().PadLeft(6, '0'); ExpiryUtc = GetExpiry(utcNow); } }
public async Task <string> GenerateQRCode(string secret) { var user = await _userManager.GetUserAsync(_httpContextAccessor.HttpContext.User); QRCodeGenerator qrGenerator = new QRCodeGenerator(); var buffer = Base32.ToByteArray(secret); var secretBase32 = Base32.ToString(buffer); string payload = $"otpauth://totp/BorovClub:{user.Email}?secret={secret}&issuer=BorovClub&algorithm=SHA1&digits=6&period=30"; QRCodeData qrCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q); Base64QRCode qrCode = new Base64QRCode(qrCodeData); string qrCodeImageAsBase64 = qrCode.GetGraphic(20); user.TwoFactorEnabled = true; user.TotpSecret = secretBase32; await _userManager.UpdateAsync(user); await _dbContext.SaveChangesAsync(); return(qrCodeImageAsBase64); }