brandonpotter / googleauthenticator Goto Github PK
View Code? Open in Web Editor NEWSimple, easy to use server-side two-factor authentication library for .NET that works with Google Authenticator and Authy.
License: Apache License 2.0
Simple, easy to use server-side two-factor authentication library for .NET that works with Google Authenticator and Authy.
License: Apache License 2.0
Currently ValidateTwoFactorPIN only accepts UTF8 encoded string, which in my opinion is not correct as not every byte sequence is valid UTF8 string. And for the setup there is overload that accepts byte[]. So the same should be for ValidateTwoFactorPIN.
The build on master does not appear to put the package into the artifacts folder. Need to dig into.
Re-introduce the changes proposed in PR #11 to skip QR code generation
bool isValid = TwoFacAuth.ValidateTwoFactorPIN(UserUniqueKey, token);
I have tried above code but, the code always returning false even if unique key and token is correct.
ValidateTwoFactorPin always returns false, if the secretKey parameter is base32 encoded string. It happens because this parameter is always converted to a byte array in the GenerateHashedCode method using Encoding.UTF8.GetBytes method.
In the case of base32 encoded string, we need to use the method Base32Encoding.ToBytes.
Add support for SourceLink to the package
Hello! I have such a problem: there is a format key of JFCGY43BOZZG6QTH. The resulting six-digit code using your code is different from the six-digit code obtained using the google authenticator mobile application. Tell me, maybe I'm doing something wrong? Please show me an example.
We've got something odd going on. We've got a moderately large solution - about 60 projects in the solution, using .NET 4.8. We have three targets set up for our build, Debug, Test and Release. With the latest version of your product (v2.2.0) only with our test build, we have suddenly started getting method not found for any of the methods we try to access. It works perfectly well when we compile for Debug. It's just when we compile for our Test release. We have had to drop back to the 2.1.1 release to resolve the issue for now.
The Pack process fails due to the WebSample and WinTest projects. Can we easily exclude those?
Build and run tests on Linux as well as Windows (assuming Linux works in the first place)
I noticed that the url generated by QrCodeSetupImageUrl is not secure. Created a workaround: string.Replace("http","https"). Maybe it is an options to add an method called: QrCodeSetupImageUrlSecure
string url = String.Format("{0}://chart.googleapis.com/chart?cht=qr&chs={1}x{2}&chl={3}", protocol, qrCodeWidth, qrCodeHeight, provisionUrl);
"Warning: This API is deprecated."
https://developers.google.com/chart/infographics/docs/qr_codes
You should probably move away from using the Google QR code generator as it is a deprecated API that could be removed at any time.
This blog also highlights the risk of using externally generated QR codes for Google authenticator as the QR code contains cryptography secrets. It also suggests that QR codes can be generated locally using javascript as a solution.
http://blog.geuer-pollmann.de/blog/2014/12/15/generating-qr-codes-in-html/
Changing your QR generation so that it is locally generated would increase security and also allow for local intranet usage where an internet connection may not be available. If there is no internet connection you would currently not be able to generate a QR code.
Edit: I'm currently using this pure C# QR renderer https://github.com/codebude/QRCoder
Add a build badge to Readme.
API has changed so I need to look at it again :)
Copy the documentation from the external blog post to the readme.
I'm using GoogleAuthenticator version 2.1.1 it's working fine on local Windows machine but when I publish it on Linux the QR code is notgenerated anymore.
Before I was using version 2.0.0 that Time I had the below Exception
System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'libdl' or one of its dependencies
Then I upgraded the Sysytem.Drawing to 5.0.0 and upgraded GoogleAuthenticator to 2.1.1 after that it's not giving any Exception in Linux server but no QR Code is generated.
on the web I found a solution like below, not sure if it works.
# install System.Drawing native dependencies RUN apt-get update \ && apt-get install -y --allow-unauthenticated \ libc6-dev \ libgdiplus \ libx11-dev \ && rm -rf /var/lib/apt/lists/*
The package is not working on dedicated server. Although it is working fine on AWS server. And I can;t make difference why something is happening.
Please i need your help out there
version of google authenticator is 1.2.1
Here is my code:
public Boolean ValidateTwoFactorPIN(User user)
{
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
var verificationCode = user.Code.Replace(" ", string.Empty).Replace("-", string.Empty);
bool data = tfa.ValidateTwoFactorPIN(user.SharedKey, verificationCode, TimeSpan.FromSeconds(60));
return data;
}
public async Task<User> LoadSharedKeyAndQrCodeUriAsync(User user)
{
if (!user.Is2faEnabled)
{
var uniqueUserKey = RandomString(30).Replace(" ", string.Empty).Replace("-", string.Empty);
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
var setupInfo = tfa.GenerateSetupCode("My Application",user.UserName, uniqueUserKey, 300, 300);
user.AuthenticatorUri = setupInfo.QrCodeSetupImageUrl;
user.AuthenticationCode = setupInfo.ManualEntryKey;
user.SharedKey = setupInfo.AccountSecretKey;
_unitOfWork.UserRepository.Update(user);
await _unitOfWork.Commit();
}
return user;
}
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
Using the same two factor code from client to validate (more then once) via ValidateTwoFactorPIN validates successfully whereas the code should be expired once used.
It expired only after the given time is lapsed. ... i.e. if time lapse was 30 seconds and i validate same two factor code from client more then once within 30 seconds, it will always give me success where as once used, it should expire.
There does not appear to be any included feature to link a device with an account.
Is that smoething that needs to be done separately?
If so, it may be worth pointing that out in the Readme, together with a small amoount of info as to what a recommended way might be to achieve that, or links to useful info about it.
As it stands, there is a risk of someone using this, thinking it is a full 2fa solution, as opposed to a 2fa component.
Regards.
Looks like as of V2 the AccountSecretKey
is no longer used or populated so should be removed.
Looks like QRCoder just upgraded to 1.4.2 the other day; now I get this error when loading GoogleAuthenticator:
System.IO.FileLoadException: 'Could not load file or assembly 'QRCoder, Version=1.4.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)'
If I use nuget to downgrade QRCoder to 1.4.1, it works.
Also seeing this in the decompilation of TwoFactorAuthenticator.cs in visual studio:
Resolve: 'QRCoder, Version=1.4.1.0, Culture=neutral, PublicKeyToken=null'
Found single assembly: 'QRCoder, Version=1.4.2.0, Culture=neutral, PublicKeyToken=c4ed5b9ae8358a28'
WARN: Version mismatch. Expected: '1.4.1.0', Got: '1.4.2.0'
Load from: 'C:\Users\ericb\Documents\logbook\packages\QRCoder.1.4.2\lib\net40\QRCoder.dll'
I ran into an issue with the code throwing an InvalidOperationException when calling ValidateTwoFactorPIN on a machine with the "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signatures" Local Policy set to Enabled (default is Disabled). As we have some sites dealing potentially with federal data we need to leave this on for compliance reasons.
I traced the issue down to line 182 in internal string GenerateHashedCode(byte[] key, long iterationNumber, int digits = 6)
where the SHA1 cryptography was being created.
HMACSHA1 hmac = new HMACSHA1(key, true);
According to https://msdn.microsoft.com/en-us/library/ms223095(v=vs.110).aspx, the second parameter indicates whether to use the managed implementation of the SHA1 algorithm – true uses SHA1Manager and false uses SHA1CryptoServiceProvider. Apparently SHA1Manager is not FIPS compliant but SHA1CryptoServiceProvider is.
I think this second parameter should be configurable to allow the user to specify using the managed SHA1 class or not.
Is there a .NET Core version of this? Or planned?
As @ahwm pointed out, the last few releases have not been deployed to Nuget and the releases have expired in AzDO.
Would you be able to run a release to get it deployed please @BrandonPotter?
Whenever I've tried to set the code length in my authenticator app to be larger than 6 digits the verification seems to fail. It doesn't seem to be a timing issue as it does work consistently with 6-digit codes.
while trying to generate qr code following crash occurs:
System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+.
at System.Drawing.SafeNativeMethods.Gdip.CheckStatus(Int32 status)
at System.Drawing.Graphics.FillRectangle(Brush brush, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.FillRectangle(Brush brush, Rectangle rect)
at QRCoder.QRCode.GetGraphic(Int32 pixelsPerModule, Color darkColor, Color lightColor, Boolean drawQuietZones)
at QRCoder.QRCode.GetGraphic(Int32 pixelsPerModule)
not very helpful exception, maybe you need some more details?
Encoding account names with Uri.EscapeUriString gets rid of the arbitrary "account name without spaces" requirement. It would be nice of the library could do this automatically.
Notes:
EncodeAccountSecretKey(string accountSecretKey)
System.Text.ASCIIEncoding.Default.GetBytes(accountSecretKey));
GenerateHashedCode(string secret, long iterationNumber, int digits = 6)
byte[] key = Encoding.ASCII.GetBytes(secret);
Base32 encoding supports Unicode so you should consider changing both of the above to use UTF-8 as ASCII limits the key space you can use reducing security and compatibility with other implementations where codes are auto generated random bytes.
Encoding.UTF8.GetBytes(secret)
You also run into the ASCII encoding converting anything that is not recognised into a question mark.
https://msdn.microsoft.com/en-us/library/system.text.encoding.ascii%28v=vs.110%29.aspx
The ASCIIEncoding object that is returned by this property might not have the appropriate behavior for your app. It uses replacement fallback to replace each string that it cannot encode and each byte that it cannot decode with a question mark ("?") character.
Might also be nice to see overloads to allow for secrets to also be used in Base32 encoded or Byte[] format instead of just original plain text like it currently is which makes Unicode implementation a bit less flexible.
I came across this issue creating the QR Code image inside a docker container with limited resources in RAM, the container starts with 140mb of ram and once I call the endpoint to create the image it goes up to 1.7 GB of Ram just after calling the method. Is there a way we can reduce this.
This was using Aspnetcore 2.2 and GoogleAuthenticator v2.0.1
Method that generated the spike: GenerateSetupCode
Suggestion: Add a develop
branch and some version numbering so you can easily merge PRs into develop and have them automatically published as pre-release versions on Nuget.
I can set it up easily enough - if you want it?
@BrandonPotter we need you to update the NuGet API key in Pipelines.
Message received:
The specified API key is invalid, has expired, or does not have permission to access the specified package.
@BrandonPotter @ahwm I have just added an "approval" step on the azure pipeline that pushes the new version to Nuget - hope that is okay?
It's just to avoid errors like when the readme changes were merged, we got a report that it had failed to deploy to Nuget because the version number hadn't changed.
Having an approval step will allow us a bit of breathing space to merge multiple PRs before we push a new version to Nuget.
If I have set it up correctly, all three of us have been set up to approve so either of us can do it.
Also, would be nice to be able to chat outside of issues :) If you use Twitter, can you ping me @flytzen?
The code works well. I have also tested with a different QR code generator. But one thing I can't seem to figure out is why the manual code is not accepted in my 2FA app (Authenticator Plus). If I scan the code, it works fine. If I try to enter the code manually, it says it is too short.
I checked another app and I see that the manual code on that one is 16 characters. And that does work. So why is the manual code too short???
Looking at the QR generation code because of issue #50 and came across this:
shouldn't we have
else { throw; }
in this one and the one below to avoid swallowing exceptions?
I was able to figure out that if you're not logged in it gives an error as the response. If I hit the pipelines page and get logged in, then I can see the badge.
{"count":1,"value":{"Message":"Build pipeline BrandonPotter.GoogleAuthenticator was not found."}}
Any ideas, @flytzen ?
the method UrlEncode(string value) in class TwoFactorAuthenticator not Not compatible Chinese,it can not Encode Chinese rightly,so when i use GA app to scan qrcode,it doesn't show a issure name or account name.i created a class that exdents class TwoFactorAuthenticator and change the method UrlEncode(string value) to call method WebUtility.UrlEncode(value),now it work with chinese.
Any way to issue backup codes with this?
Are we ready to release 2.0?
Should we push the 2.0.0-beta1 package and let it sit there for a bit to let people find issues?
Are we aware of anything we need to do before releasing 2.0?
In a "from scratch" asp.net website (.net 4.8/webforms), I was able to put together a prototype that generated a QR code that I was able to scan using my iPhone authy app. Pretty much exactly as your WebSample code. All good.
So, I moved on to adding the same code to my current/active/production website code. And now when setting the .ImageUrl property to the generated string, I'm getting an HTTP 400/Bad Request error. The image tag rendered on page is just a broken link image. I used the browser DevTools to find the bad "get" request that shows:
Status: 400 Bad Request
Version: HTTP/1.1
Transferred: 503 B (324 B size)
Referrer Policy: strict-origin-when-cross-origin
So I'm guessing this has something to do with CORS and all things related to "cross origin" requests? Any suggestions would be appreciated.
You rely on System.Drawing.Common (via QRCoder) which has known issues on Linux and will be removed (marked as platform-specific) in .NET 6.0 here the official announcement https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only
Got following warning on pipelines build
##[warning]The windows-2016 environment is deprecated and will be removed on March 15, 2022. Migrate to windows-latest instead. For more details, see https://github.com/actions/virtual-environments/issues/4312
I have just set up a new computer and it is no longer possible to add a developer pack for .Net 4.5; only 4.5.1 and 4.5.2 are available.
I can still compile from the commandline, but VS 2022 won't compile the solution.
If we change support to 4.5.2, we'll have to increment the major version number. But, when #69 is resolved, we will almost certainly need to drop support for 4.5.x anyway - so probably better to wait and see what the next version of QR Coder supports, align ourselves with that and release a major version then?
Será que tem algum limite para a utilização? Se sim, como resolver?
Hi @BrandonPotter,
Azure is now building the nuget package. To make it easier to publish to Nuget, I suggest setting up a release pipeline with approval; every time a commit to master
succeeds, you will be asked if you want to deploy that package to NuGet.
In order to finish setting up that release pipeline, I need you to set up a "Service Connection". First, you need to create an API key in Nuget, then add it to the Azure DevOps pipeline:
If easy - for backwards compatibility
Please add a LICENSE file that details the license terms to use the code/nuget package, etc.
We should add DependaBot and update dependencies before the next release:
https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/enabling-and-disabling-dependabot-version-updates
This should also pick up when a release comes out that fixes #69
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.