Seyed Amin
Seyed Amin

Reputation: 81

OtpSharp not working with google authenticator

I've been trying to use OtpSharp along with Google Authenticator in an application I'm developing. However, I don't understand why the code produced by OtpSharp does not match that of Google Authenticator. I've even tried to correct the time input to OtpSharp according to my local OS without any luck. On another note, the pyotp library from python works just fine without any special effort. Here is the code I'm using:

var bSharedKey = System.Text.Encoding.Unicode.GetBytes("TESTTESTTESTTEST");
//var correction = new TimeCorrection(DateTime.UtcNow.ToLocalTime());
//var totp = new Totp(bSharedKey, timeCorrection: correction);
var totp = new Totp(bSharedKey);
var realOtp = totp.ComputeTotp();
long timestep = 0;
var OTPmatch = totp.VerifyTotp(passwords[1], out timestep);

Upvotes: 1

Views: 2020

Answers (2)

Mohammad Dayyan
Mohammad Dayyan

Reputation: 22458

I used the following solution:
First
Choose a secret key.
e.g: 32 Chars

private const string SecretKey = "hfBhdVsbAWXmkdWrcnwezQqVLubqeRdq";

Second
Use an approach to generate QR code with your secret.
e.g:
https://stefansundin.github.io/2fa-qr/ How to generate a QR Code for Google Authenticator that correctly shows Issuer displayed above the OTP?

Point Key: You have to convert your secret key to Base32 to generate QR Code. You can use https://emn178.github.io/online-tools/base32_encode.html to convert a string to base32 online

Third
Install OtpSharp nuget package.
Validate entered token as follows:
XXX: Valid Period In Seconds

private static bool Validate(string token)
    {
        var totp = new Totp(Encoding.UTF8.GetBytes(SecretKey));
        return totp.VerifyTotp(DateTime.UtcNow.AddSeconds(XXX), token, out _, new VerificationWindow(2, 2));
    }

Upvotes: 1

Seyed Amin
Seyed Amin

Reputation: 81

The problem was that instead of providing an arbitrary unicode key to the pyotp library (as well as to Google Authenticator), a Base32 string was needed as the input, which I assume was later decoded to a byte array and used by the library.

So I provided OtpSharp with the byte string representation of an arbitrary unicode string and used an online website to decode the unicode string to a base32 string, and used the base32 string in Google Authenticator.

To put it simply, Otpsharp requires a byte array to initialize a totp object, while pyotp needs you to provide it with a base32 string.

Upvotes: 2

Related Questions