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

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

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

Suggesstions吗?想法吗?


当前回答

对于这种类型的密码,我倾向于使用可能生成更容易“使用”的密码的系统。短的,通常由发音片段和一些数字组成,并且没有字符间的歧义(这是0还是O?是1还是I?)类似的

string[] words = { 'bur', 'ler', 'meh', 'ree' };
string word = "";

Random rnd = new Random();
for (i = 0; i < 3; i++)
   word += words[rnd.Next(words.length)]

int numbCount = rnd.Next(4);
for (i = 0; i < numbCount; i++)
  word += (2 + rnd.Next(7)).ToString();

return word;

(直接在浏览器中输入,因此仅作为参考。同时,要多加单词)。

其他回答

由于Random是不安全的,RNGCryptoServiceProvider是过时的,我最终这样做:

  // possible characters that password can have
  private const string passChars =
       "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
       "abcdefghijklmnopqrstuvwxyz" +
       "0123456789" +
       "!@#$%.-_"
       ;

    public static string GetRandomPassword(int length)
    {
        char[] p = new char[length];
        for (int i = 0; i < length; i++)
            p[i] = passChars[RandomNumberGenerator.GetInt32(0, passChars.Length)];
        return new string(p);
    }
 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();
    }
public string CreatePassword(int length)
{
        const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            res.Append(valid[rnd.Next(valid.Length)]);
        }
        return res.ToString();
}

这有一个很好的好处,可以从可用的字符列表中选择生成的密码(例如,仅数字,仅大写或仅小写等)。

我一直对KeePass内置的密码生成器非常满意。因为KeePass是一个。net程序,而且是开源的,所以我决定深入研究一下它的代码。最后,我只是在我的项目中引用了标准应用程序安装中提供的KeePass.exe副本,并编写了下面的代码。多亏了KeePass,你可以看到它是多么灵活。你可以指定长度,包含/不包含哪些字符,等等。

using KeePassLib.Cryptography.PasswordGenerator;
using KeePassLib.Security;


public static string GeneratePassword(int passwordLength, bool lowerCase, bool upperCase, bool digits,
        bool punctuation, bool brackets, bool specialAscii, bool excludeLookAlike)
    {
        var ps = new ProtectedString();
        var profile = new PwProfile();
        profile.CharSet = new PwCharSet();
        profile.CharSet.Clear();

        if (lowerCase)
            profile.CharSet.AddCharSet('l');
        if(upperCase)
            profile.CharSet.AddCharSet('u');
        if(digits)
            profile.CharSet.AddCharSet('d');
        if (punctuation)
            profile.CharSet.AddCharSet('p');
        if (brackets)
            profile.CharSet.AddCharSet('b');
        if (specialAscii)
            profile.CharSet.AddCharSet('s');

        profile.ExcludeLookAlike = excludeLookAlike;
        profile.Length = (uint)passwordLength;
        profile.NoRepeatingCharacters = true;

        KeePassLib.Cryptography.PasswordGenerator.PwGenerator.Generate(out ps, profile, null, _pool);

        return ps.ReadString();
    }

灵感来自@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();
    }
}