/// <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 SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, byte[] accountSecretKey, int QRPixelsPerModule)
        {
            if (accountTitleNoSpaces == null)
            {
                throw new NullReferenceException("Account Title is null");
            }
            accountTitleNoSpaces = RemoveWhitespace(accountTitleNoSpaces);
            string encodedSecretKey = Base32Encoding.ToString(accountSecretKey);
            string provisionUrl     = null;

            if (String.IsNullOrWhiteSpace(issuer))
            {
                provisionUrl = String.Format("otpauth://totp/{0}?secret={1}", accountTitleNoSpaces, encodedSecretKey);
            }
            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, UrlEncode(issuer));
            }
            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);

                                return(new SetupCode(accountTitleNoSpaces, encodedSecretKey, String.Format("data:image/png;base64,{0}", Convert.ToBase64String(ms.ToArray()))));
                            }
        }
Ejemplo n.º 2
0
        /// <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, should be 10 or less)</param>
        /// <returns>SetupCode object</returns>
        public SetupCode GenerateSetupCode(string issuer, string accountTitleNoSpaces, byte[] accountSecretKey, int QRPixelsPerModule = 3, 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)
            {
                try
                {
                    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 = String.Format("data:image/png;base64,{0}", Convert.ToBase64String(ms.ToArray()));
                                    }
                }
                catch (System.TypeInitializationException e)
                {
                    if (e.InnerException != null &&
                        e.InnerException.GetType() == typeof(System.DllNotFoundException) &&
                        e.InnerException.Message.Contains("libgdiplus"))
                    {
                        throw new MissingDependencyException("It looks like libgdiplus has not been installed - see https://github.com/codebude/QRCoder/issues/227", e);
                    }
                }
                catch (System.Runtime.InteropServices.ExternalException e)
                {
                    if (e.Message.Contains("GDI+") && QRPixelsPerModule > 10)
                    {
                        throw new QRException($"There was a problem generating a QR code. The value of {nameof(QRPixelsPerModule)} should be set to a value of 10 or less for optimal results.", e);
                    }
                }
            }

            return(new SetupCode(accountTitleNoSpaces, encodedSecretKey.Trim('='), qrCodeUrl));
        }
Ejemplo n.º 3
0
 /// <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 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));
 }