Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HI,class TwoFactorAuthenticator's private method UrlEncode(string value) not Not compatible Chinese #50

Closed
coolbytebyte opened this issue Apr 16, 2020 · 5 comments · Fixed by #88
Assignees

Comments

@coolbytebyte
Copy link

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.

@ahwm
Copy link
Collaborator

ahwm commented Apr 16, 2020

That sounds great! Can you provide a copy or do a pull request?

@coolbytebyte
Copy link
Author

        private class MyTwoFactorAuthenticator : TwoFactorAuthenticator
        {
            /// <summary>
            /// Generate a setup code for a Google Authenticator user to scan
            /// </summary>
            /// <param name="issuer">Issuer ID (the name of the system, i.e. 'MyApp'), can be omitted but not recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format </param>
            /// <param name="accountTitleNoSpaces">Account Title (no spaces)</param>
            /// <param name="accountSecretKey">Account Secret Key</param>
            /// <param name="secretIsBase32">Flag saying if accountSecretKey is in Base32 format or original secret</param>
            /// <param name="QRPixelsPerModule">Number of pixels per QR Module (2 pixels give ~ 100x100px QRCode)</param>
            /// <returns>SetupCode object</returns>
            public new SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, string accountSecretKey,
                bool secretIsBase32, int QRPixelsPerModule)
            {
                byte[] key = secretIsBase32
                    ? Base32Encoding.ToBytes(accountSecretKey)
                    : Encoding.UTF8.GetBytes(accountSecretKey);
                return GenerateSetupCode(issuer, accountTitleNoSpaces, key, QRPixelsPerModule);
            }

            /// <summary>
            /// Generate a setup code for a Google Authenticator user to scan
            /// </summary>
            /// <param name="issuer">Issuer ID (the name of the system, i.e. 'MyApp'), can be omitted but not recommended https://github.com/google/google-authenticator/wiki/Key-Uri-Format </param>
            /// <param name="accountTitleNoSpaces">Account Title (no spaces)</param>
            /// <param name="accountSecretKey">Account Secret Key as byte[]</param>
            /// <param name="QRPixelsPerModule">Number of pixels per QR Module (2 = ~120x120px QRCode)</param>
            /// <returns>SetupCode object</returns>
            public new SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, byte[] accountSecretKey,
                int QRPixelsPerModule, bool generateQrCode = true)
            {
                if (String.IsNullOrWhiteSpace(accountTitleNoSpaces))
                {
                    throw new NullReferenceException("Account Title is null");
                }

                accountTitleNoSpaces = RemoveWhitespace(Uri.EscapeUriString(accountTitleNoSpaces));
                string encodedSecretKey = Base32Encoding.ToString(accountSecretKey);
                string provisionUrl;
                if (String.IsNullOrWhiteSpace(issuer))
                {
                    provisionUrl = String.Format("otpauth://totp/{0}?secret={1}", accountTitleNoSpaces,
                        encodedSecretKey.Trim('='));
                }
                else
                {
                    //  https://github.com/google/google-authenticator/wiki/Conflicting-Accounts
                    // Added additional prefix to account otpauth://totp/Company:[email protected] for backwards compatibility
                    provisionUrl = String.Format("otpauth://totp/{2}:{0}?secret={1}&issuer={2}", accountTitleNoSpaces,
                        encodedSecretKey.Trim('='), UrlEncode(issuer));
                }

                string qrCodeUrl = string.Empty;
                if (generateQrCode)
                {
                    using (QRCodeGenerator qrGenerator = new QRCodeGenerator())
                    using (QRCodeData qrCodeData = qrGenerator.CreateQrCode(provisionUrl, QRCodeGenerator.ECCLevel.Q))
                    using (QRCode qrCode = new QRCode(qrCodeData))
                    using (Bitmap qrCodeImage = qrCode.GetGraphic(QRPixelsPerModule))
                    using (MemoryStream ms = new MemoryStream())
                    {
                        qrCodeImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

                        qrCodeUrl = $"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}";
                    }
                }

                return new SetupCode(accountTitleNoSpaces, encodedSecretKey.Trim('='), qrCodeUrl);
            }

            private static string RemoveWhitespace(string str)
            {
                return new string(str.Where(c => !Char.IsWhiteSpace(c)).ToArray());
            }


            private string UrlEncode(string value)
            {
                //Solve the problem of invalid Chinese escape
                return WebUtility.UrlEncode(value);
            }
        }

@flytzen flytzen self-assigned this Jun 19, 2020
@flytzen flytzen added the bug label Jun 19, 2020
@AmmonLin
Copy link

@flytzen
Use Uri.EscapeDataString instead of Uri.EscapeUriString, UrlEncode(issuer) will solve this issue.
For more information about uri escape, see stackoverflow answer.

@flytzen
Copy link
Collaborator

flytzen commented Dec 6, 2021

@ahwm FYI: I did some work on this over the weekend but didn't finish it. I am trying to add some tests to the QR code but it's proving challenging. If we are in a rush we can skip the tests, but otherwise, I'd like to get them in there ;)

@ahwm
Copy link
Collaborator

ahwm commented Dec 7, 2021

I don't think we're in a rush.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants