Generating a strong password in C#?

Viewed 38570

I was wondering how I can generate a strong and secure password in C#.

I googled a little bit and saw this formula in Wikipedia, where L is the length of the password and N is the number of possible symbols:

alt text

Also, I've found this question, but for some reason the method Membership.GeneratePassword just returns a random number with 1 digit, which absolutely no password. All the rest solutions, were very slow (>= 0.5 secs).

I need help implementing this formula (I don't know where to start). You may also suggest another solution or explain why the GeneratePassword isn't working.

7 Answers

I just tried the following in linqpad:

System.Web.Security.Membership.GeneratePassword(25, 10)

This is the password I got:

[XTJ_67g.i/ag1rL)6_Yv>*+%

Or, if that's not secure enough, try this:

System.Web.Security.Membership.GeneratePassword(128, 100)

which got me the following when running it three times:

|c^.:?m)#q+(]V;}[Z(})/?-;$]+@!|^/8*_9.$&.&!(?=^!Wx?[@%+&-@b;)>N;&+*w[>$2+_$%l;+h+#zhs^{e?&=*(}X_%|:}]]}*X[+)Er%J/-=;Q0{:+=%c7:^$

/:_)hxF+*){2|;(>:*N^+!_&|}B.$})?[V=[+v({-:-@9-Z$j?.[-}(@MHx+}(}Mz_S(7#4}{..>@G|!+++{+C=|_}=+r^@&$0;L*|kz-;$++/N3$=}?;%&]]*/^#^!+

:*{]-x^$g{|?*))_=B@^.#%L;g|+)#[nq}?y(_(m;]S^I$*q=l-[_/?}&-!k^(+[_{Z|&:^%!_)!=p%=)=wYd-#.UP$%s1{*l%+[%?!c+7=@=.;{+M)!^}&d/]{];(&}

this took way less than a second, btw. The framework is your friend.

See http://msdn.microsoft.com/en-us/library/system.web.security.membership.generatepassword.aspx

To address your question about that formula:

The formula is saying that a password of length L drawn from an alphabet of N symbols is equivalent to a password of length H drawn from an alphabet of two symbols. So if you have, say, 64 symbols (say abc...xyzABC...XYZ01...89_!) and the password is 10 characters long, then that gives you equivalent security to a password 10 log2 64 = 60 characters long drawn from the alphabet "ab".

A "log" is the inverse operation of exponentiation. Two to the sixth power gives you sixty-four, therefore the "log two" of sixty-four gives you six.

I don't know if this will help you, but this is what I use when I want to generate a random password which is also strong. It's quick and simple to implement/understand and isn't as much of an overkill as the one through the membership provider above...

    private string Token(byte Length) {
        char[] Chars = new char[] {
            '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',
            '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',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
        };
        string String = string.Empty;
        Random Random = new Random();

        for (byte a = 0; a < Length; a++) {
            String += Chars[Random.Next(0, 61)];
        };

        return (String);
    }

Why not just fill an array with some characters and pick on random a number of them. You can divide them in groups to be sure that are include letters numbers and special characters.

You will also have to pick a proper length and how much of every group of characters to include and that's it. I don't think you need some sophisticated formulas.

For systems that don't allow user-generated passwords it's very easy, actually: Any password is as secure as it's long. Not counting, of course, people who tack post-its to monitors, etc.

You probably want to maximize the set of characters from which the password is generated. But restricting the generated passwords greatly reduces the search space and therefore makes the password less secure. Again, this only holds if the user can't choose their own password.

If you deal with both generated and user-created passwords, then all bets are off, obviously. You then probably want to generate the passwords in a way that it uses as many characters from different classes as possible, resembling a strong user-chosen password. Ideally it should conform to the same constraints that the user-created password has to pass as well (if any).

I'd use Guid myself :), and make the user edit the password after login

Related