# Is a random number secure (enough) for card numbers and pins?

I've been given the task of generating some gift tokens which comprise a serial number and a pin number, analagous to a pre-paid credit card. The serial and pin will be printed on a card, with the pin behind a scratch panel.

My first thought is for both numbers to be randomly generated with the serial number being unique. Is this secure against guessing?

To my simple mind, adding any kind of logic would make the numbers more gussable as there'd then be something to figure out and understand, whereas random is without reason (ignoring implementation details for now), and so while being simple using pure random gives the attacker less to work with.

Is this a flawed assumption? Are there known "good" ways of doing this?

If the numbers are random, the attacker has nothing to work with, and you can trivially calculate his probability of guessing a correct combination.

If you have some kind of brute-force prevention triggering well below the level where a random guess has a reasonable chance of success, you should be good.

I would agree that any kind of logic would give the attacker more to work with. If you create a large number of such tokens, you might want to add some extra processing to ensure that no two randomly generated numbers are too close to each other (to eliminate typos, maybe even to allow one typo as a convenience - all depends on the length, etc.). With a low number of tokens, I wouldn't bother unless their value is very high.

I think is a reasonable approach, the most important aspect will be how hard the pin numbers are to guess - a 6 digit pin will take more effort than a 3 digit pin for example. The larger you can make the length of the pin number without compromising usability the better, I'd suggest no less than 6 digits.

The maths is fairly simple: 3 digits means 1000 combinations so 1/1000 chance of guessing correctly. 6 digits means 1,000,000 combinations so 1/1,000,000

You will also need to rate limit how many times a pin can be guessed and decide what to do when that rate limit is reached. If the serial number is visible then you may want to consider a delay before the pin can be tried again rather than locking out the card to prevent someone deliberately locking all cards they can see.

As for not allowing certain patterns, I'd say this isn't entirely necessary, however you may want to restrict the most guessable ones such as '000000', '999999', '123456' etc.

• Interesting point about common patterns. Jun 4, 2020 at 10:00
• To further increase how hard the pin is to guess, you can include alpha-numeric characters. The maths now becomes 36^pin length - so with 6 alpha-numeric digits there's a 1 in 2,176,782,336‬ chance of guessing correctly. Jun 4, 2020 at 10:02
• Don't bother restricting things that "look" random. That just makes the end result less random.... Jun 4, 2020 at 11:50

It is, indeed, more secure to determine the pin at random, just like actual credit cards. However, you should prevent the pin from having more that 2 or 3 times the same number in a pin, depending on the lenght of said pin. `4425`is acceptable, `4445`or `4424` isn't.

• that's interesting. Do you have more background info on why? How is three of the same digit less secure/more guessable than three different digits? Jun 4, 2020 at 9:51
• Removing numbers that follow patterns from a small space of numbers (up to at least 6 digits) is not a good idea. You will be left with very few numbers. If an attacker knows the patterns which are excluded, brute-forcing/guesing existing pins becomes much easier. Jun 4, 2020 at 9:54
• Greg B : It makes it more easy to "guess" because the basic technique is to guess by changing one digit at the time. However as BenjaminH said, if you were to create a bruteforce algorithm and be aware of this technique, it can reduce the time required to bruteforce the pin (As you would exclude a lot of potential pin that would have made the attack more complex). It depends on the Threat model and use of said pin. If you have to use it "by hand" in a machine it is a good idea. If you have to enter it on a website/app where it can be bruteforced, that wouldn't be such a great idea. Jun 4, 2020 at 9:59
• @BenjaminH I always thought that eliminating repeating numbers has nothing to do with guessability or security, but with convenience - if you enter your card number somewhere, you can get lost if there's a 55555 in there - "wait, was that three 5s or four already?". If the digits change, you always know which was the last digit you entered.
– Tom
Jun 5, 2020 at 5:01