Giter Site home page Giter Site logo

twofactorauth.net's Introduction

Logo .Net library for Two Factor Authentication

Build status NuGet version License PayPal donate button

.Net library, available as NuGet package, for two-factor (or multi-factor) authentication using TOTP and QR-codes. This is a .Net port of the PHP TwoFactorAuth library (staying as close as possible to the PHP implementation, but using .Net conventions and codestyles).

Requirements

Installation

To install TwoFactorAuth.Net, run the following command in the Package Manager Console

PM> Install-Package TwoFactorAuth.Net

Quickstart

Step 1: Set up secret shared key

When a user wants to setup two-factor auth (or, more correctly, multi-factor auth) you need to create a secret. This will be your shared secret. This secret will need to be entered by the user in their app. This can be done manually, in which case you simply display the secret and have the user type it in the app:

var tfa = new TwoFactorAuth("MyCompany");
// Though the default is an 80 bits secret (for backwards compatibility reasons) we 
// recommend creating 160+ bits secrets (see RFC 4226 - Algorithm Requirements)
var secret = tfa.CreateSecret(160);

The CreateSecret() method accepts two arguments: bits (default: 80) and cryptoSecureRequirement (default: RequireSecure). The former is the number of bits generated for the shared secret. Make sure this argument is a multiple of 8 and, again, keep in mind that not all combinations may be supported by all apps. Google Authenticator seems happy with 80 and 160, the default is set to 80 because that's what most sites (that I know of) currently use; however a value of 160 or higher is recommended (see RFC 4226 - Algorithm Requirements). The latter is used to ensure that the secret is cryptographically secure; if you don't care very much for cryptographically secure secrets you can specify AllowInsecure and use a non-cryptographically secure RNG provider.

// Display shared secret
<p>Please enter the following secret in your app: @secret</p>

This results in:

Please enter the following secret in your app: XANIK3POC23RCRYN

Another, more user-friendly, way to get the shared secret into the app is to generate a QR-code which can be scanned by the app. To generate these QR codes you can use any one of the built-in QRProvider classes:

...use a 3rd party one or implement your own QR Code provider. To implement your own provider all you need to do is implement the IQrCodeProvider interface. You can use the built-in providers mentioned before to serve as an example or read the next chapter in this file. The built-in classes all use a 3rd (e.g. external) party (Google, QRServer and QRicket) for the hard work of generating QR-codes (note: each of these services might at some point not be available or impose limitations to the number of codes generated per day, hour etc.). You could, however, easily use any library to generate your QR-codes without depending on external sources. See HowTo: Implement your own QR Code provider on how to do this.

The built-in providers all have some provider-specific 'tweaks' you can 'apply'. Some provide support for different colors, others may let you specify the desired image-format etc. What they all have in common is that they return a QR-code as binary blob which, in turn, will be turned into a data URI by the TwoFactorAuth class. This makes it easy for you to display the image without requiring extra 'roundtrips' from browser to server and vice versa.

// Display QR code to user
<p>Scan the following image with your app:</p>
<p><img src="@tfa.GetQrCodeImageAsDataUri("Bob Ross", secret)"></p>

This results in:

Scan the following image with your app:

Step 2: Verify secret shared key

When the shared secret is added to the app, the app will be ready to start generating codes which 'expire' each period number of seconds. To make sure the secret was entered, or scanned, correctly you need to verify this by having the user enter a generated code. To check if the generated code is valid you call the VerifyCode() method:

// Verify code
tfa.VerifyCode((string)Session["secret"], code);

VerifyCode() will return either true (the code was valid) or false (the code was invalid; no points for you!). You may need to store secret in a session or other persistent storage between requests. The VerifyCode() accepts, aside from secret and code, two more arguments. The first being discrepancy. Since TOTP codes are based on time("slices") it is very important that the server (but also client) have a correct date/time. But because the two may differ a bit we usually allow a certain amount of leeway. Because generated codes are valid for a specific period (remember the period argument in the TwoFactorAuth's constructor?) we usually check the period directly before and the period directly after the current time when validating codes. So when the current time is 14:34:21, which results in a 'current timeslice' of 14:34:00 to 14:34:30 we also calculate / verify the codes for 14:33:30 to 14:34:00 and for 14:34:30 to 14:35:00. This gives us a 'window' of 14:33:30 to 14:35:00. The discrepancy argument specifies how many periods (or: timeslices) we check in either direction of the current time. The default discrepancy of 1 results in (max.) 3 period checks: -1, current and +1 period. A discrepancy of 4 would result in a larger window (or: bigger time difference between client and server) of -4, -3, -2, -1, current, +1, +2, +3 and +4 periods.

The second, dateTime or timestamp (depending on which overload you use), allows you to check a code for a specific point in time. This argument has no real practical use but can be handy for unittesting etc. Unless specified TwoFactorAuth uses the current time.

The third, timeSlice, is an out-argument; the value returned in timeSlice is the value of the timeslice that matched the code (if any). This value will be 0 when the code doesn't match and non-zero when the code matches. This value can be stored with the user and can be used to prevent replay-attacks. All you need to do is, on successful login, make sure timeSlice is greater than the previously stored timeslice.

Step 3: Store secret with user

Ok, so now the code has been verified and found to be correct. Now we can store the secret with our user in our database (or elsewhere) and whenever the user begins a new session, after logging in, we ask for a code generated by the authentication app of their choice. All we need to do is call VerifyCode() again with the shared secret we stored with the user and the entered code and we'll know if the user is legit or not.

Simple as 1-2-3!

See also

Building TwoFactorAuth.Net

You'll need to have Sandcastle Help File Builder (SHFB) installed if you want to build the helpfile. Other than that you only need Visual Studio 2015 (or higher).

License

Licensed under MIT license. See LICENSE for details.

Logo / icon under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication (Archived page)

twofactorauth.net's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twofactorauth.net's Issues

Code from Mobile QR Image is not accepting

Hi

The code from Mobile QR image is not accepting in my application. The verify code is always returns false and timeslice value is always zero. But when I use tfa.GetCode() method, the value is accepting and verify code returns true and slice value is greater than zero.

My implementation is below and please let me know what I am missing or doing wrongly.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TwoFactorAuthNet;

namespace TFAuthentication
{
    ///  Steps to Implement QR Code implementation
    ///  Step 1: Add GenerateQRCode Image Button in User Account aspx. 
    ///  Step 2: Add Image Tag in User Account aspx to dispay QR Code Image.
    ///  Step 3: Call GenerateTFSharedSecret
    ///  Step 4: Call AddTwoFactorAuthentication
    ///  Step 5: Call GenerateQrCodeImage and display QR Code Image in aspx.
    ///  Step 6: Add QR Code Validate ASPX page
    ///  Step 7: Call ValidateQRCode to validate the QR Code entered by the user.
    public static class TFAIdentity
    {
        /// <summary>
        ///  Generate Two Factor Shared Secret. Store the secret with User. This will be used only when user wants to generate/re-generate the QR Code image.
        /// </summary>
        /// <returns>User Two Factor Authentication Shared Secret </returns>
        public static string GenerateTFSharedSecret()
        {
            var tfa = new TwoFactorAuth("MyOrg",6, 30, Algorithm.SHA256);
            var secret = tfa.CreateSecret(160);
            return secret;
        }
        /// <summary>
        ///   Generate QR Code Image and it will be used as img src in aspx page
        /// </summary>
        /// <param name="label">User Name</param>
        /// <param name="secret"></param>
        /// <returns>QR Code Image Source as string </returns>
        public static string GenerateQrCodeImage(string label, string secret)
        {
            var tfa = new TwoFactorAuth("MyOrg",6, 30, Algorithm.SHA256);
            return tfa.GetQrCodeImageAsDataUri(label, secret);
        }
        /// <summary>
        /// Validate the QR Code entered by the User. This method will be used every time the user wants to login into the application.
        /// </summary>
        /// <param name="code"></param>
        /// <param name="secret"></param>
        /// <returns>Boolean</returns>
        public static bool VerifyQrCode(string code, string secret)
        {
            var verifyCode = false;
            var tfa = new TwoFactorAuth("MyOrg",6, 30, Algorithm.SHA256);
            var a1 = tfa.GetCode(secret);
           // The below Line is working 
           verifyCode = tfa.VerifyCode(secret, a1,out long timeSlice1);
           // The below line is not working. Code from Mobile Authenticator
            verifyCode = tfa.VerifyCode(secret, code,out long timeSlice2);
            
            return true;
        }
        /// <summary>
        ///  Update the User Shared Secret in Users Table.
        /// </summary>
        /// <param name="email"></param>
        /// <param name="secret"></param>
        public static void AddTwoFactorAuthentication(string email, string secret)
        {
            var connectionString = ConfigurationManager.AppSettings["connectMyOrgAPP"];
            using (var conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string sqlQuery = "UPDATE Users SET SharedSecret = @sharedSecret, TFAEnabled=@TFAEnabled  WHERE email = @email";
                using (var cmd = new SqlCommand(sqlQuery, conn))
                {
                    cmd.Parameters.AddWithValue("sharedSecret", secret);
                    cmd.Parameters.AddWithValue("TFAEnabled", 1);
                    cmd.Parameters.AddWithValue("email", email);
                    cmd.ExecuteNonQuery();
                }
            }
        }
        /// <summary>
        ///  Remove User Two Factor Authentication for the user.
        /// </summary>
        /// <param name="email"></param>
        public static void RemoveTwoFactorAuthentication(string email)
        {
            var connectionString = ConfigurationManager.AppSettings["connectMyOrgAPP"];
            using (var conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string sqlQuery = "UPDATE Users SET SharedSecret = @sharedSecret, TFAEnabled=@TFAEnabled  WHERE email = @email";
                using (var cmd = new SqlCommand(sqlQuery, conn))
                {
                    cmd.Parameters.AddWithValue("sharedSecret", string.Empty);
                    cmd.Parameters.AddWithValue("TFAEnabled", 0);
                    cmd.Parameters.AddWithValue("email", email);
                    cmd.ExecuteNonQuery();
                }
            }
        }
        /// <summary>
        ///  Check user enabled the Two Factor Authentication
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static bool IsTwoFactorEnabled(string email)
        {
            var connectionString = ConfigurationManager.AppSettings["connectMyOrgAPP"];
            var isEnabled = false;
            using (var conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string sqlQuery = "SELECT TFAEnabled FROM Users WHERE email = @email";
                using (var cmd = new SqlCommand(sqlQuery, conn))
                {
                    cmd.Parameters.AddWithValue("email", email);
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            isEnabled = bool.Parse(reader["TFAEnabled"].ToString());
                            break;
                        }
                    }
                }
            }
            return isEnabled;
        }
        /// <summary>
        ///  Retrieves User Shared Secret from Customers Table based on User Id
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static string GetUserSharedSecret(string email)
        {
            var connectionString = ConfigurationManager.AppSettings["connectMyOrgAPP"];
            var sharedSecret = string.Empty;
            using (var conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string sqlQuery = "SELECT SharedSecret FROM Users WHERE email = @email";
                using (var cmd = new SqlCommand(sqlQuery, conn))
                {
                    cmd.Parameters.AddWithValue("email", email);
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            sharedSecret = reader["SharedSecret"].ToString();
                            break;
                        }
                    }
                }
            }
            return sharedSecret;
        }
    }
}

My ASPX code is below

<td class="Content" width="100%">
	<table border="0" cellpadding="0" cellspacing="0" width="100%">
		<tr>
			<td class="Content">
				<p><img src="<%=Me.QrCodeImage%>" alt="QRCode" /> </p>
				<br />
			</td>
		</tr>
		 <tr>
			<td class="Content">
					<asp:Button ID="RemoveTFA" Text="Disable Two Factor Authentication" runat="server"  OnClick="RemoveTFA_Click"/>
			</td>
		</tr>
	</table>
</td>

My ASPX code behind is below

Try
	If Not IsPostBack Then
		Dim email As String = user.Email
		Dim isTFAEnabled As Boolean
		Dim sharedSecret As String = String.Empty
		// Get TFA Information from Users Table
		isTFAEnabled = TFAIdentity.IsTwoFactorEnabled(email)
		If isTFAEnabled Then
			sharedSecret = TFAIdentity.GetUserSharedSecret(email)
		End If
		//Store the secret in Session
		If String.IsNullOrEmpty(sharedSecret) Then
			sharedSecret = TFAIdentity.GenerateTFSharedSecret()
			Session("sharedSecret") = sharedSecret
		End If

		'Generate QR Code Image
		QrCodeImage = TFAIdentity.GenerateQrCodeImage(email, sharedSecret)
		 // If not enabled then enable and store the secret in users table
		If Not isTFAEnabled Then
			'Update Shared Secret to Users Table
			TFAIdentity.AddTwoFactorAuthentication(email, sharedSecret)
		End If

	End If
Catch ex As Exception
	Response.Redirect("../error.htm")
End Try

Referenced assembly 'TwoFactorAuth.Net.dll' does not have a strong name

I've tried to install and use this 2FA library using nuget in my solution, but I get the following error when trying any of the classes/methods:

Referenced assembly 'TwoFactorAuth.Net.dll' does not have a strong name

I've checked the dll using sn.exe and indeed it says:

TwoFactorAuth.Net.dll does not represent a strongly named assembly

I have signing turned on in my projects and I don't want to disable it, but I also don't want to have to sign library dll's myself, since it makes updating from nuget more difficult.

Can you help me with this? Thanks in advance!

How to get the code to manually add to authenticator

Beside the QRcode it would be nice to have the manual code to enter into the Authentication App.
If I send the QR to a phone they can't scan it :-)
So I want to have the code available to enter it manually.

Which function to use ?
Or is it the Secret generated by CreateSecret()

Thanks !

Question: Are timeslices opaque?

The new option to return timeslice after successful validation is great. I was wondering if a client app could make any assumptions about the value. For example, I would like to be able to get the datetime associated with the timeslice. Tentatively, I have coded this:

public DateTime GetUtcDateTimeForTimeSlice(long timeslice)
{
    long unixTimeStamp = timeslice * PERIOD;

    // Unix timestamp is seconds past epoch
    System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
    dtDateTime = dtDateTime.AddSeconds(unixTimeStamp);

    return dtDateTime;

}

Certainly, not asking for anything new in the library because it's fine as-is, but wondering if you think interpreting the meaning of the timeslice in this way is acceptable.

Additional document request: thread saftey

I'm wondering if the methods provided by TwoFactorAuth are thread safe. If they are, it would make the most sense in apps to create a single long-lived instance of TwoFactorAuth. To use throughout your app.

Convert to .NET Standard

Hi, I'm currently working on a .NET Core project, and I was interested in using TwoFactorAuth.Net as a two factor auth provider.

I was wondering if you'd be interested in converting the project to a .NET Standard project, as it would make the process much easier.

The biggest problem as-is is the use of the System.Drawing package . There's not a direct replacement for this that works cross-platform, though their are alternatives.

It looks like System.Drawing is only required if you're actually manipulating the QR codes, which aren't critical. There's a couple of options there, but possibly the easiest is just to cross-compile the app, and only include the System.Drawing methods in the net461 version

If you're happy to go this route, we'd probably need to convert to the new csproj style in VC2017.

I'm happy to do the bulk of the conversion work if this is something you're interested in, but just wanted to gauge your feelings on it first.

QRCodeProvider - make GetUri public

To prevent the extra hop of downloading QR-image from the provider and then transferring it to the the client again - allow us to insert the URL into client's HTML directly.

Also your code for the default provider is the not most efficeint one (uses webclient - no connection caching, no async call etc, bu that's another issue)

Instagram TOTP Codes are Invalid

Good afternoon,

I'm trying to make TwoFactorAuth.NET work with Instagram. When enabling 2FA Instagram gives you a Base32 string of characters. Using this string here, I would expect the codes TwoFactorAuth.NET would generate accurate 6 digit TOTP responses:

Dim TFA As New TwoFactorAuth
Dim Code As String = TFA.GetCode("xxxx")
Call Console.WriteLine("[*] TOTP 2FA Code: " & Code)

Even after iterating through each timezone when trying to generate codes the TwoFactorAuth.NET codes are invalid. The codes are also different than what Google Authenticator when generating codes at the same time for the same Base32 string, and those codes work. I have a .Net solution and an exemplar account I would be happy to give you access to privately in support of any troubleshooting you might be able to help me with.

VerifyCode(secret, code, n, out slice) returns invalid timeslice value

The new methods are working great for my application, but there seems to be a bug.
I am getting slice values that are separated by as little as 6 seconds, and they are not multiples of 30 seconds. Here is some code:

 for (; ; )
            {
                Console.Write("Enter the Google code: ");
                string code = Console.ReadLine();
                if (code == "")
                    break;

                if (tfa.VerifyCode(secret, code, 2, out slice))
                {
                    if (slice <= lastMatchingTimeSlice)
                        Console.WriteLine("Code is valid, but you already used it");
                    else
                    {
                        Console.WriteLine("Valid code!");
                        lastMatchingTimeSlice = slice;
                    }
                }
                else
                    Console.WriteLine("Invalid code");

                Console.WriteLine();
            }

I assume the timeslice value is supposed to be a unix timestamp rounded down to the previous 30 second boundary, and that it represents the timeslice associated with the matched code.

But I see the following values on one iteration:

slice = 1528241471
lastMatchingTimeslice = 1528241465

Is this a bug? What I am seeing is that my code fails to detect code reuse if the same code is entered twice.

MS Authenticator shows email domain when using email as label (account name) instead of issuer

If I use an email address as the "label" in creating the QR code, Microsoft Authenticator uses the domain from the email as the Issuer, rather than the provided issuer.

To wit:
EX 1 - Not Email (i.e. sample code):

  • private readonly TwoFactorAuth tfa = new TwoFactorAuth("MyCompany", qrcodeprovider: new QRCoder.QRCoderQRCodeProvider());
  • Model.GetQrCodeImageAsDataUri("Bob Ross", (string)Session["secret"])"

RESULT:
image

EX 2 - Email Label:

  • private readonly TwoFactorAuth tfa = new TwoFactorAuth("MyCompany", qrcodeprovider: new QRCoder.QRCoderQRCodeProvider());
  • img src="@Model.GetQrCodeImageAsDataUri("[email protected]", (string)Session["secret"])"
    RESULT:
    image

image

However, the email DOES work properly in Google Authenticator:
image

Any ideas?

Add support for app Icon

TOTP supports showing an icon next to an authentication item, for example in Microsoft Authenticator you can see the GitHub icon next to the GitHub item.

Request: Add support for this.

How to display the QR Code in MVC view

When I try to use the code from the readme, it gives error "the name 'tfa' doe not exist"

// Display QR code to user
<p>Scan the following image with your app:</p>
<p><img src="@tfa.GetQrCodeImageAsDataUri("Bob Ross", secret)"></p>

When I try to use the code in a controller and then send it to MVC view, I get error on tfa.GetQRCodeImageAsDataUri...
"System.Net.WebException: 'The request was aborted: Could not create SSL/TLS secure channel."

De aanvraag is afgebroken: Kan geen beveiligd SSL/TLS-kanaal maken. bij System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) bij System.Net.WebClient.DownloadData(Uri address) bij TwoFactorAuthNet.Providers.Qr.BaseHttpQrCodeProvider.DownloadData(Uri address) bij TwoFactorAuthNet.TwoFactorAuth.GetQrCodeImageAsDataUri(String label, String secret, Int32 size)

Any idea how to fix it ?

var tfa = new TwoFactorAuth("Bob Ross");
var secret = tfa.CreateSecret(160);
Session["TFAsecret"] = secret;

ContactTFAModel cm = new ContactTFAModel();
cm.IDKey = IDKey;
cm.URI = tfa.GetQrCodeImageAsDataUri("Bob Ross", secret);
cm.ReturnUrl = ViewBag.ReturnUrl;
return View(cm);

Intermittently getting timeout exception when generating QR code uri

Hello,

I'm getting a very occasional exception when generating the QR code uri. This is not occuring every call, but bombs out occasionally.

C# code is the following.

var tfa = new TwoFactorAuth("test1");
var secret = tfa.CreateSecret(160);
var qrCodeUri = tfa.GetQrCodeImageAsDataUri(User.FindFirst(ClaimTypes.Name).Value, secret);

Stack Trace of Error is Below

	"Message": "The operation has timed out.",
	"Type": "System.Net.WebException",
	"StackTrace": [
	  "
at System.Net.HttpWebRequest.GetResponse()\n
at System.Net.WebClient.GetWebResponse(WebRequest request)\n
at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream)\n
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)\n
at System.Net.WebClient.DownloadData(Uri address)\n
at TwoFactorAuthNet.Providers.Qr.BaseHttpQrCodeProvider.DownloadData(Uri address)\n
at TwoFactorAuthNet.TwoFactorAuth.GetQrCodeImageAsDataUri(String label, String secret, Int32 size)

Use this library as SMS authenticator

I wanted to use this to generate a code and sent it via SMS or EMAIL to the user, and the user would use the generated code to login.

If I generate a key for the user tfa.CreateSecret(180); I end with a very long hex-token, How can I can generate a code from it without using QR, I need the code to emai/smsl it to the user instead of the hex-token (secret).

Can I use this lib for this purpose ? Thank you.

Not able to configure TwoFactorAuth.net with Authenticator Apps [Not sure its an issue or limitation]

Hi,

Am currently trying to use TwoFactorAuth.net with Authenticator apps but failing to do so if I try to customize the constructor.

Example
If am trying to create an instance with the following constructor

New TwoFactorAuth(AppName,
            OTPLength,
            Period,
            Algorithm.SHA256,
            New ISL.Security.Provider.BasicQRCodeProvider())

Issue 1:
If OTPLength is set to 8 or so, the authenticator app only generates 6 digits.
Issue 2:
If Period is set to 4 mins or so, the authenticator app always expires in 30 seconds.

If we use the default construtor - everything falls in place
New TwoFactorAuth(AppName)
Where it takes default values of 6 digits and 30 seconds

PS
Tried Google and Microsoft Authenticator app

Please help me with the same.

Generate URL and code for non-QR option

I'm trying to add two factor authentication to my system. We want to support account addition with non-QR options (say, user's camera isn't working so they pick "Enter Code Manually").
On Windows Authenticator, it requires a numeric code, and a URL. I've gone over the documentation and came up short with how to generate these through this library.
What did I miss? And is this even supported?

Not Working in Microsoft Authenticator App but in Google Authenticator

Hi,

i'm using the following code to generate QRCode for TOTP:

tfa = new TwoFactorAuth("ADRM", 6, 60);

secret = tfa.CreateSecret(80, CryptoSecureRequirement.RequireSecure);

secretlabel.Text = secret;


AppSettingsHandler.Handler.AddOrUpdateSetting("secret", secret);


              

String uri = tfa.GetQrText("ADRM", secret);


QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(uri, QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(20);

                


pictureBox1.Image = qrCodeImage;

My Problem is that if i scan the Code with Microsoft Authenticator i get an other code as Google Authenticator.

Googles Code is correct, microsoft's isnt.

Can you help please?

optauth Uri not fully compatible with Microsoft Authenticator

Microsoft Authenticator ignores the issuer when it is included in the querystring portion of the Uri. In this case it takes only the label.

This can be fixed by including the issuer/service provider before the label in path portion of the Uri as described here: https://github.com/google/google-authenticator/wiki/Key-Uri-Format

eg. otpauth://totp/Example: [email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example

I've only tested with Microsoft Authenticator and Google Authenticator, but they both work with this format.

Return time window value for successful verification

It's too bad there is not a method to return the matching time slot value when a verification is successful.

Our desired method of preventing code reuse would be to store that value, and ensure any new attempts use a slot that is greater.

You probably get the gist, but this whole area is something not well defined, and your library (as nice as it is), does not seem to help with this.

Maybe I'm missing something in the library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.