3

I'm working on a Hotspot service, using ASP.NET Core building a MVC application, and i need do generate a 6-digit (100000 to 999999) number to serve as the password for the user to connect and have internet access. That number needs to be unique in the database and it will be removed after some time (line a month).

What is the best way to generate this unique number? I'm using Entity Framework aswell and was wondering if that could help me in some way with this problem...

Thanks in advance!

Travis J
  • 81,153
  • 41
  • 202
  • 273
Taichou Sama
  • 31
  • 1
  • 3
  • 1
    Is the password the only thing that grants access? Is a username or the like also required to grant access? Having a 6-digit password allows for only 900,000 possibilities, which makes it vulnerable to brute-force guessing attacks. Did you consider requiring a much longer password or another way to authenticate users of your hotspot? Did you consider one-time password protocols? See also what I wrote about generating [random unique identifiers](https://peteroupc.github.io/random.html#Unique_Random_Identifiers). – Peter O. Apr 16 '20 at 19:02
  • Finally, for generating the password itself, you should use a cryptographic RNG; see my section on [existing APIs](https://peteroupc.github.io/random.html#Existing_RNG_APIs_in_Programming_Languages). – Peter O. Apr 16 '20 at 19:02
  • EF is an OR/mapper, it's not concerned with generating random numbers or anything. – Gert Arnold Apr 16 '20 at 20:22

3 Answers3

5

Well, it's easy enough to just do something like:

var rand = new Random();
var uid = rand.Next(100000, 1000000);

However, the only way to ensure uniqueness in the database would be to 1) query to ensure the value doesn't exist first (though there's concurrency issues there) or 2) make the column unique, and catch DB exceptions thrown from constraint validations.

In short, you have to do something in concert with the database to determine whether it's actually unique in the database. With a pool of less than a million, you're likely to get collisions quite often.

It's worth mentioning, as @PeterO points out, this isn't going to be remotely secure. It would be trivially easy to brute force a collision from a pool of less than a million candidates. However, using cryptographic RNG isn't going to help here if you're still ending up with a 6-character numeric. How you get a random number doesn't matter as much as the how random that number can actually be. The entropy here is next to zero.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
1

Due to the randomisation being based on the time, you cannot be certain a number will be unique. If by unique you mean that it should be unique in the database what you can do is retrieve all the passwords from the database and generate a random number (new Random().Next(100000, 1000000)) and generate it again until you can't find a match. But I would not advise using a 'basic' password even for a short period of time.

BenceL
  • 804
  • 6
  • 13
0

For generating the password itself, you should use a cryptographic RNG (such as RNGCryptoServiceProvider in .NET); see my section on existing APIs for various programming languages. Using System.Random is not appropriate here, since the random password is designed for authentication purposes and System.Random is not designed for security.

However, there are several problems with the approach you are taking.

Is the password the only thing that grants access? Is a username or the like also required to grant access?

Having a 6-digit password allows for only 900,000 possibilities, which makes it vulnerable to brute-force guessing attacks. Due to the birthday problem, a little more than the square root of 900,000 guesses (a little more than 950) is enough to hit a valid password, and the chance of hitting a valid password increases the more passwords there are in the database.

Did you consider requiring a much longer password or another way to authenticate users of your hotspot?

Did you consider one-time password protocols?

See also what I wrote about generating random unique identifiers.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • I see your point, i confess taht the idea of a brute-force gess never passed through my mind... I Could raise the digits, but the thing is that the company already works only with teh password, and that being numbers, do you have an idea of how many digits I could put it to kinda? I could see to work with characters too, something like "s9d8ge" insead of "652324", what do you think? – Taichou Sama Apr 16 '20 at 19:23
  • A UUID (version 4) contains hyphens, 32 other characters, and 122 bits of randomness; you can generate one using the `Guid.NewGuid()` method in .NET. It could serve a password for your purposes, and it has hyphens to aid the memory. Alternatively, you can generate 16 random bytes using a cryptographic RNG and transform those bytes to a "hex string" similar to a UUID. – Peter O. Apr 16 '20 at 19:29