Reputation: 31
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!
Upvotes: 3
Views: 6561
Reputation: 32898
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.
Upvotes: 0
Reputation: 239400
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.
Upvotes: 5
Reputation: 844
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.
Upvotes: 1