Pin Generation

2020-05-15 04:17发布

I am looking to develop a system in which i need to assign every user a unique pin code for security. The user will only enter this pin code as a means of identifying himself. Thus i dont want the user to be able to guess another users pincode. Assuming the max users i will have is 100000, how long should this pin code be?

e.g. 1234 4532 3423

Should i generate this code via some sort of algorithm? Or should i randomly generate it?

Basically I dont want people to be able to guess other peoples pincode and it should support enough number of users.

Am sorry if my question sounds a bit confusing but would gladly clarify any doubts.

thank you very much.

UPDATE

After reading all the posts below, I would like to add some more detail.

  1. What i am trying to achieve is something very similar to a scratch card.
  2. A user is given a card, which he/she must scratch to find the pin code.
  3. Now using this pin code the user must be able to access my system.

I cannot add extra security (e.g. username and password), as then it will deter the user from using the scratch card. I want to make it as difficult as possible to guess the pincode within the limitations.

thankyou all for your amazing replies again.

11条回答
\"骚年 ilove
2楼-- · 2020-05-15 04:26

Lots of great answers so far: simple, effective, and elegant!

I'm guessing the application is somewhat lottery-like, in that each user gets a scratch card and uses it to ask your application if "he's already won!" So, from that perspective, a few new issues come to mind:

War-dialing, or its Internet equivalent: Can a rogue user hit your app repeatedly, say guessing every 10-digit number in succession? If that's a possibility, consider limiting the number of attempts from a particular location. An effective way might be simply to refuse to answer more than, say, one attempt every 5 seconds from the same IP address. This makes machine-driven attacks inefficient and avoids the lockout problem.

Lockout problem: If you lock an account permanently after any number of failed attempts, you're prone to denial of service attacks. The attacker above could effectively lock out every user unless you reactivate the accounts after a period of time. But this is a problem only if your PINs consist of an obvious concatenation of User ID + Key, because an attacker could try every key for a given User ID. That technique also reduces your key space drastically because only a few of the PIN digits are truly random. On the other hand, if the PIN is simply a sequence of random digits, lockout need only be applied to the source IP address. (If an attempt fails, no valid account is affected, so what would you "lock"?)

Data storage: if you really are building some sort of lottery-like system you only need to store the winning PINs! When a user enters a PIN, you can search a relatively small list of PINs/prizes (or your equivalent). You can treat "losing" and invalid PINs identically with a "Sorry, better luck next time" message or a "default" prize if the economics are right.

Good luck!

查看更多
虎瘦雄心在
3楼-- · 2020-05-15 04:31

I've done this before with PHP and a MySQL database. I had a permutations function that would first ensure that the number of required codes - $n, at length $l, with the number of characters, $c - was able to be created before starting the generation process.

Then, I'd store each new code to the database and let it tell me via UNIQUE KEY errors, that there was a collision (duplicate). Then keep going until I had made $n number of successfully created codes. You could of course do this in memory, but I wanted to keep the codes for use in a MS Word mail merge. So... then I exported them as a CSV file.

查看更多
手持菜刀,她持情操
4楼-- · 2020-05-15 04:41

May I suggest an alternative approach? Take a look at Perfect Paper Passwords, and the derivatives it prompted .

You could use this "as is" to generate one-time PINs, or simply to generate a single PIN per user.

Bear in mind, too, that duplicate PINs are not of themselves an issue: any attack would then simply have to try multiple user-ids.

(Mileage warning: I am definitely not a security expert.)


Here's a second answer: from re-reading, I assume you don't want a user-id as such - you're just validating a set of issued scratch cards. I also assume you don't want to use alphabetic PINs.

You need to choose a PIN length such that the probability of guessing a valid PIN is less than 1/(The number of attempts you can protect against). So, for example, if you have 1 million valid PINs, and you want to protect against 10000 guesses, you'll need a 10-digit PIN.

If you use John Graham-Cumming's version of the Perfect Paper Passwords system, you can:

  1. Configure this for (say) 10-digit decimal pins
  2. Choose a secret IV/key phrase
  3. Generate (say) the first million passwords(/PINs)

I suspect this is a generic procedure that could, for example, be used to generate 25-alphanumeric product ids, too.

Sorry for doing it by successive approximation; I hope that comes a bit nearer to what you're looking for.

查看更多
SAY GOODBYE
5楼-- · 2020-05-15 04:41

There's a difference between guessing the PIN of a target user, and that of any valid user. From your use case, it seems that the PIN is used to gain access to certain resource, and it is that resource that attackers may be after, not particular identities of users. If that's indeed the case, you will need to make valid PIN numbers sufficiently sparse among all possible numbers of the same number digits.

As mentioned in some answers, you need to make your PIN sufficiently random, regardless if you want to generate it from an algorithm. The randomness is usually measured by the entropy of the PIN.

Now, let's say your PIN is of entropy N, and there are 2^M users in your system (M < N), the probability that a random guess will yield a valid PIN is 2^{M-N}. (Sorry for the latex notations, I hope it's intuitive enough). Then from there you can determine if that probability is low enough given N and M, or compute the required N from the desired probability and M.

There are various ways to generate the PINs so that you won't have to remember every PIN you generated. But you will need a very long PIN to make it secure. This is probably not what you want.

查看更多
萌系小妹纸
6楼-- · 2020-05-15 04:44

If we assume 100,000 users maximum then they can have unique PINs with 0-99,999 ie. 5 digits.

However, this would make it easier to guess the PINs with the maximum number of users. If you can restrict the number of attempts on the PIN then you can have a shorter PIN. eg. maximum of 10 failed attempts per IP per day.

It also depends on the value of what you are protecting and how catastrophic it would be if the odd one did get out.

I'd go for 9 digits if you want to keep it short or 12 digits if you want a bit more security from automated guessing.

To generate the PINs, I would take a high resolution version of the time along with some salt and maybe a pseudo-random number, generate a hash and use the first 9 or 12 digits. Make sure there is a reasonable and random delay between new PIN generations so don't generate them in a loop, and if possible make them user initiated.

eg. Left(Sha1(DateTime + Salt + PseudoRandom),9)

查看更多
Luminary・发光体
7楼-- · 2020-05-15 04:44

It seems you want to use the pin code as the sole means of identification for users. A workable solution would be to use the first five digits to identify the user, and append four digits as a PIN code.

If you don't want to store PINs they can be computed by applying a cryptographically secure hash (SHA1 or better) to the user number plus a system-wide secret code.

查看更多
登录 后发表回答