0

We are using the following methods to create temporary passwords, I am wondering if this is a good practice, since Random is not truly random. Beside the fact that we should generate it with another list of valid characters I highly doubt that this is random enough:

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

Should we add some other randomness e.g. process Id or something similar? Or maybe "new Random" just needs a some kind of salt?

The question I am asking here is more specific, since I am asking about specific problems with the given code I am providing. My question is not how to generate random temporary passwords, but how the code I am providing is problematic and why the answers and suggestions are better in these regards. Maybe I should have posted it in the "Code Reivew" Stack. But I personally do not see it as exact dupblicate of the other question.

Matthias
  • 1,386
  • 3
  • 24
  • 59
  • Here is a little salt advice from Microsoft: [link](https://msdn.microsoft.com/en-us/library/aa288534(v=vs.71).aspx) – ntohl Aug 11 '15 at 13:04
  • 2
    I think you should move Random out of the method and use its only instance instead of creating it again and again – Rohit Aug 11 '15 at 13:06
  • I think they talk about password encryption and not generation. Not sure. – Matthias Aug 11 '15 at 13:06
  • According to this definition it uses the system clock seed when you provide nothing. So it should be OK to have it inside the method? https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx – Matthias Aug 11 '15 at 13:09
  • 1
    @Matthias You need to use the same instance of `Random` if you generate numbers quickly like that. See this example: https://dotnetfiddle.net/fMV8nM – Jason P Aug 11 '15 at 13:15
  • OK. So actually it is the same as it was in C in the old days. Since the seed will always be the same (system clock does not change that face). It generates the same over and over again. This is probably a bug if you need to create multiple passwords at a team. We should initialise the Random instance probably even at application startup? – Matthias Aug 11 '15 at 13:17
  • Cool Fiddle! It helped me to see immediately the problem. – Matthias Aug 11 '15 at 13:18
  • I think you could phrase a good answer out of this? – Matthias Aug 11 '15 at 13:19
  • 1
    Well, it depends. If you think you might be generating more than one password at a time, it could be a problem. You might create a `PasswordGenerator` class that has a static instance of `Random` to use. Otherwise, you might just use the built in `System.Web.Security.Membership.GeneratePassword()` that kyle suggested so you don't have to worry about it. – Jason P Aug 11 '15 at 13:20
  • System.Web is a bit outdated I think. When we want to be ready for vNext. But I did not says that in my initial question. – Matthias Aug 11 '15 at 13:21
  • possible duplicate of [Generating Random Passwords](http://stackoverflow.com/questions/54991/generating-random-passwords) – Rohit Aug 12 '15 at 11:02
  • @kyle: I think my question is different in terms of the code I am providing. Also if I look at the comments these are valuable for my situation. I think it is good enough to link the two questions. – Matthias Aug 12 '15 at 11:54

2 Answers2

2

You need to use a cryptographically secure pseudo random number generator (CSPRNG). e.g.

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(saltValue);

Using Random is seeded by current time of day. This means that an attacker could generate the same password as a user using this function if they know (or guess) the time of day that it was generated. A cryptographically secure random function does not have this flaw:

CSPRNG requirements fall into two groups: first, that they pass statistical randomness tests; and secondly, that they hold up well under serious attack, even when part of their initial or running state becomes available to an attacker

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
1

For web application I think you can use System.Web.Security.Membership.GeneratePassword(int length, int numberOfNonAlphanumericCharacters).

Rohit
  • 10,056
  • 7
  • 50
  • 82
  • Sounds interesting, but I would be interested also in if the approach we are using is reasonable or not. I will think about using what you provide here. – Matthias Aug 11 '15 at 13:04