ASP.NET Identity : Generate random password

前端 未结 6 1105
天涯浪人
天涯浪人 2021-02-02 10:50

Is there any built in function that creates random passwords ? Asp.net simple memebership used to have a similar method

6条回答
  •  孤街浪徒
    2021-02-02 11:40

    I know this is a bit of an old question, and there have been others who put out source for randomly generating passwords but Membership.GeneratePassword is implemented like this:

    Luckily this is licensed under The MIT License https://github.com/Microsoft/referencesource/blob/master/LICENSE.txt

    public class PasswordStore
    {
            private static readonly char[] Punctuations = "!@#$%^&*()_-+=[{]};:>|./?".ToCharArray();
            private static readonly char[] StartingChars = new char[] { '<', '&' };
            /// Generates a random password of the specified length.
            /// A random password of the specified length.
            /// The number of characters in the generated password. The length must be between 1 and 128 characters. 
            /// The minimum number of non-alphanumeric characters (such as @, #, !, %, &, and so on) in the generated password.
            /// 
            ///  is less than 1 or greater than 128 -or- is less than 0 or greater than . 
            public static string GeneratePassword(int length, int numberOfNonAlphanumericCharacters)
            {
                if (length < 1 || length > 128)
                    throw new ArgumentException("password_length_incorrect", nameof(length));
                if (numberOfNonAlphanumericCharacters > length || numberOfNonAlphanumericCharacters < 0)
                    throw new ArgumentException("min_required_non_alphanumeric_characters_incorrect", nameof(numberOfNonAlphanumericCharacters));
                string s;
                int matchIndex;
                do
                {
                    var data = new byte[length];
                    var chArray = new char[length];
                    var num1 = 0;
                    new RNGCryptoServiceProvider().GetBytes(data);
                    for (var index = 0; index < length; ++index)
                    {
                        var num2 = (int)data[index] % 87;
                        if (num2 < 10)
                            chArray[index] = (char)(48 + num2);
                        else if (num2 < 36)
                            chArray[index] = (char)(65 + num2 - 10);
                        else if (num2 < 62)
                        {
                            chArray[index] = (char)(97 + num2 - 36);
                        }
                        else
                        {
                            chArray[index] = Punctuations[num2 - 62];
                            ++num1;
                        }
                    }
                    if (num1 < numberOfNonAlphanumericCharacters)
                    {
                        var random = new Random();
                        for (var index1 = 0; index1 < numberOfNonAlphanumericCharacters - num1; ++index1)
                        {
                            int index2;
                            do
                            {
                                index2 = random.Next(0, length);
                            }
                            while (!char.IsLetterOrDigit(chArray[index2]));
                            chArray[index2] = Punctuations[random.Next(0, Punctuations.Length)];
                        }
                    }
                    s = new string(chArray);
                }
                while (IsDangerousString(s, out matchIndex));
                return s;
            }
    
            internal static bool IsDangerousString(string s, out int matchIndex)
            {
                //bool inComment = false;
                matchIndex = 0;
    
                for (var i = 0; ;)
                {
    
                    // Look for the start of one of our patterns 
                    var n = s.IndexOfAny(StartingChars, i);
    
                    // If not found, the string is safe
                    if (n < 0) return false;
    
                    // If it's the last char, it's safe 
                    if (n == s.Length - 1) return false;
    
                    matchIndex = n;
    
                    switch (s[n])
                    {
                        case '<':
                            // If the < is followed by a letter or '!', it's unsafe (looks like a tag or HTML comment)
                            if (IsAtoZ(s[n + 1]) || s[n + 1] == '!' || s[n + 1] == '/' || s[n + 1] == '?') return true;
                            break;
                        case '&':
                            // If the & is followed by a #, it's unsafe (e.g. S) 
                            if (s[n + 1] == '#') return true;
                            break;
                    }
    
                    // Continue searching
                    i = n + 1;
                }
            }
    
            private static bool IsAtoZ(char c)
            {
                if ((int)c >= 97 && (int)c <= 122)
                    return true;
                if ((int)c >= 65)
                    return (int)c <= 90;
                return false;
            }
        }
    

提交回复
热议问题