当我们网站上的用户丢失密码并转到丢失密码页面时,我们需要给他一个新的临时密码。我并不介意这有多随机,或者它是否符合所有“所需的”强密码规则,我想做的只是给他们一个他们以后可以更改的密码。

该应用程序是用c#编写的Web应用程序。所以我想刻薄一点,走一条简单的路线,用Guid的一部分。即。

Guid.NewGuid().ToString("d").Substring(1,8)

Suggesstions吗?想法吗?


当前回答

如果你想使用System.Web.Security.Membership.GeneratePassword使用的加密安全随机数生成,但又想将字符集限制为字母数字字符,你可以使用regex过滤结果:

static string GeneratePassword(int characterCount)
{
    string password = String.Empty;
    while(password.Length < characterCount)
        password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
    return password.Substring(0, characterCount);
}

其他回答

我喜欢生成密码,就像生成软件密钥一样。您应该从遵循良好实践的字符数组中进行选择。采用@Radu094回答的内容并修改它以遵循良好的实践。不要把每个字母都放在字符数组中。有些信在电话里更难读懂。

您还应该考虑对生成的密码使用校验和,以确保它是由您生成的。实现这一点的一个好方法是使用LUHN算法。

 Generate random password of specified length with 
  - Special characters   
  - Number
  - Lowecase
  - Uppercase

  public static string CreatePassword(int length = 12)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*";

        var middle = length / 2;
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            if (middle == length)
            {
                res.Append(number[rnd.Next(number.Length)]);
            }
            else if (middle - 1 == length)
            {
                res.Append(special[rnd.Next(special.Length)]);
            }
            else
            {
                if (length % 2 == 0)
                {
                    res.Append(lower[rnd.Next(lower.Length)]);
                }
                else
                {
                    res.Append(upper[rnd.Next(upper.Length)]);
                }
            }
        }
        return res.ToString();
    }

我创建的这个方法类似于会员资格提供程序中可用的方法。如果你不想在某些应用程序中添加web引用,这是很有用的。

效果很好。

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        Random rd = new Random();

        if (NonAlphaNumericChars > Length || Length <= 0 || NonAlphaNumericChars < 0)
            throw new ArgumentOutOfRangeException();

            char[] pass = new char[Length];
            int[] pos = new int[Length];
            int i = 0, j = 0, temp = 0;
            bool flag = false;

            //Random the position values of the pos array for the string Pass
            while (i < Length - 1)
            {
                j = 0;
                flag = false;
                temp = rd.Next(0, Length);
                for (j = 0; j < Length; j++)
                    if (temp == pos[j])
                    {
                        flag = true;
                        j = Length;
                    }

                if (!flag)
                {
                    pos[i] = temp;
                    i++;
                }
            }

            //Random the AlphaNumericChars
            for (i = 0; i < Length - NonAlphaNumericChars; i++)
                pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];

            //Random the NonAlphaNumericChars
            for (i = Length - NonAlphaNumericChars; i < Length; i++)
                pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];

            //Set the sorted array values by the pos array for the rigth posistion
            char[] sorted = new char[Length];
            for (i = 0; i < Length; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }

如果你想使用System.Web.Security.Membership.GeneratePassword使用的加密安全随机数生成,但又想将字符集限制为字母数字字符,你可以使用regex过滤结果:

static string GeneratePassword(int characterCount)
{
    string password = String.Empty;
    while(password.Length < characterCount)
        password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
    return password.Substring(0, characterCount);
}

灵感来自@kitsu的回答。但使用RandomNumberGenerator而不是Random或RNGCryptoServiceProvider(在。net 6中已弃用),并添加了一些特殊字符。

可选参数,用于排除在使用System.Text.Json.JsonSerializer.Serialize时将转义的字符—例如&,它转义为\u0026—以便您可以保证序列化字符串的长度与密码的长度匹配。

适用于。net Core 3.0及以上版本。

public static class PasswordGenerator
{
    const string lower = "abcdefghijklmnopqrstuvwxyz";
    const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const string number = "1234567890";
    const string special = "!@#$%^&*()[]{},.:`~_-=+"; // excludes problematic characters like ;'"/\
    const string specialJsonSafe = "!@#$%^*()[]{},.:~_-="; // excludes problematic characters like ;'"/\ and &`+

    const int lowerLength = 26; // lower.Length
    const int upperLength = 26; // upper.Length;
    const int numberLength = 10; // number.Length;
    const int specialLength = 23; // special.Length;
    const int specialJsonSafeLength = 20; // specialJsonSafe.Length;

    public static string Generate(int length = 96, bool jsonSafeSpecialCharactersOnly = false)
    {
        Span<char> result = length < 1024 ? stackalloc char[length] : new char[length].AsSpan();

        for (int i = 0; i < length; ++i)
        {
            switch (RandomNumberGenerator.GetInt32(4))
            {
                case 0:
                    result[i] = lower[RandomNumberGenerator.GetInt32(0, lowerLength)];
                    break;
                case 1:
                    result[i] = upper[RandomNumberGenerator.GetInt32(0, upperLength)];
                    break;
                case 2:
                    result[i] = number[RandomNumberGenerator.GetInt32(0, numberLength)];
                    break;
                case 3:
                    if (jsonSafeSpecialCharactersOnly)
                    {
                        result[i] = specialJsonSafe[RandomNumberGenerator.GetInt32(0, specialJsonSafeLength)];
                    }
                    else
                    {
                        result[i] = special[RandomNumberGenerator.GetInt32(0, specialLength)];
                    }
                    break;
            }
        }

        return result.ToString();
    }
}