kspearrin / Otp.NET

A .NET implementation of TOTP and HOTP for things like two-factor authentication codes.
https://www.nuget.org/packages/Otp.NET
MIT License
1.05k stars 160 forks source link

VerifyTotp always fails #63

Open zyz opened 2 months ago

zyz commented 2 months ago

1.VS 2022:New ASP.NET Core Web (Model-Model-Controller) 2.Install-Package Otp.NET, Install-Package QRCoder 3.HomeController.cs using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using Web.Models; using OtpNet; using QRCoder; using System.Text;

public class HomeController : Controller { private readonly ILogger _logger; private const string Secret = "JBSWY3DPEHPK3PXP"; private const string BaseUser = "test"; private const string Issuer = "demo";

public HomeController(ILogger<HomeController> logger)
{
    _logger = logger;
}

public IActionResult Index()
{
    return View();
}

public IActionResult Qrcode()
{
    string uriString = new OtpUri(OtpType.Totp, Secret, BaseUser, Issuer).ToString();

    using QRCodeGenerator qrGenerator = new();
    using QRCodeData qrCodeData = qrGenerator.CreateQrCode(uriString, QRCodeGenerator.ECCLevel.Q);
    using PngByteQRCode qrCode = new(qrCodeData);
    {
        byte[] qrCodeImage = qrCode.GetGraphic(20);
        return File(qrCodeImage, "image/jpeg");
    }
}

public IActionResult Validate(string code)
{
    var totp = new Totp(Encoding.UTF8.GetBytes(Secret));
    var verificationWindow = VerificationWindow.RfcSpecifiedNetworkDelay;
    var isValid = totp.VerifyTotp(code, out long timeWindowUsed, verificationWindow);
    return Content(isValid ? "Success" : "Fail");
}

} 4.Views/Home/Index.cshtml @{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <img src="/Home/Qrcode" style="width: 300px;" /> <form action="/Home/Validate" method="post"> Code: <input name="code" /> <input type="submit" value="Validate" /> </form> </div> 5.run 6.Scan the QR code using APP Authenticator 7.Enter totp code, VerifyTotp always fails

zyz commented 2 months ago

Use Base32Encoding.ToBytes to resolve var totp = new Totp(Base32Encoding.ToBytes(Secret));