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

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

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

Suggesstions吗?想法吗?


当前回答

这是我快速拼凑的东西。

    public string GeneratePassword(int len)
    {
        string res = "";
        Random rnd = new Random();
        while (res.Length < len) res += (new Func<Random, string>((r) => {
            char c = (char)((r.Next(123) * DateTime.Now.Millisecond % 123)); 
            return (Char.IsLetterOrDigit(c)) ? c.ToString() : ""; 
        }))(rnd);
        return res;
    }

其他回答

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();
}

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

对于这种类型的密码,我倾向于使用可能生成更容易“使用”的密码的系统。短的,通常由发音片段和一些数字组成,并且没有字符间的歧义(这是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;

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

这个包允许你生成一个随机密码,同时流利地指出它应该包含哪些字符(如果需要):

https://github.com/prjseal/PasswordGenerator/

例子:

var pwd = new Password().IncludeLowercase().IncludeUppercase().IncludeSpecial();
var password = pwd.Next();
public string GenerateToken(int length)
{
    using (RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider())
    {
        byte[] tokenBuffer = new byte[length];
        cryptRNG.GetBytes(tokenBuffer);
        return Convert.ToBase64String(tokenBuffer);
    }
}

(你也可以让这个方法所在的类实现IDisposable,持有对RNGCryptoServiceProvider的引用,并正确地处理它,以避免重复实例化它。)

It's been noted that as this returns a base-64 string, the output length is always a multiple of 4, with the extra space using = as a padding character. The length parameter specifies the length of the byte buffer, not the output string (and is therefore perhaps not the best name for that parameter, now I think about it). This controls how many bytes of entropy the password will have. However, because base-64 uses a 4-character block to encode each 3 bytes of input, if you ask for a length that's not a multiple of 3, there will be some extra "space", and it'll use = to fill the extra.

If you don't like using base-64 strings for any reason, you can replace the Convert.ToBase64String() call with either a conversion to regular string, or with any of the Encoding methods; eg. Encoding.UTF8.GetString(tokenBuffer) - just make sure you pick a character set that can represent the full range of values coming out of the RNG, and that produces characters that are compatible with wherever you're sending or storing this. Using Unicode, for example, tends to give a lot of Chinese characters. Using base-64 guarantees a widely-compatible set of characters, and the characteristics of such a string shouldn't make it any less secure as long as you use a decent hashing algorithm.

使用Random和linq-to-objects来要求每个组都有一个很简单的方法。

随机分组 从第一组中选择随机金额 从以下组中选择剩余的随机金额

 

Random rand = new Random();
int min = 8;
int max = 16;
int totalLen = rand.Next(min, max);
int remainingGroups = 4;
                
string[] allowedLowerChars = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".Split(',');           
string [] allowedUpperChars = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z".Split(',');
string [] allowedNumbers = "1,2,3,4,5,6,7,8,9,0".Split(',');
string [] allowedSpecialChars = "!,@,#,$,%,&,?".Split(',');


var password = allowedLowerChars.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-remainingGroups--)).ToList();
password.AddRange(allowedUpperChars.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-password.Count-remainingGroups--)).ToList());
password.AddRange(allowedNumbers.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-password.Count-remainingGroups--)).ToList());
password.AddRange(allowedSpecialChars.OrderBy(c => rand.Next()).Take(totalLen-password.Count).ToList());
password = password.OrderBy(c => rand.Next()).ToList(); // randomize groups