We have an ongoing project at work in which the security is a hot topic of debate. The whole site is SSL and proposed auth process is like so:

  1. User receives a non-unique 4 digit pin number in person.
  2. User is emailed a URL with attached long(40 char or so) GUID.
  3. User visits URL and enters pin to authenticate. (pin is salted/hashed)
  4. User is prompted to set a password. (properly salted, hashed and stored)
  5. Upon visiting the site via the guid link, they will now be prompted for email/pass rather than pin. They may also visit the generic URL sans GUID and login with UN/Pass

A security consultant told us this is not good enough (I don't know the details of why at the moment). It seems sufficient to me. We don't set a password from the start because it would be impractical UX, and we change from PIN to Password so the user can use a generic login page without the guid URL.

4 Answers 4


Using the GUID as unique identifier for the user instead of the email address has benefits against low-power attackers. The URL-with-GUID has been sent through email, so it cannot be considered as really secret. Motivated attackers will spy on the network lines and see that email. However, amateurs or automated attack bots, while not being able to read other people's emails, may "guess" email addresses, but not random GUID.

The GUID has thus any relation with security only insofar as it is unpredictable, and then it would bring any good only against attackers who are not very powerful. Using the GUID does not harm, but don't believe that it really adds much protection. You might want to make sure that the GUID is generated wit the version 4 algorithm, i.e. 122 bits from a strong PRNG: though GUID aim at uniqueness, you want unpredictability, which is another beast; version 4 GUID ensure both.

Keeping in mind that the GUID is not (really) secret, your system can be described as such: there is a one-time registration password, which is a four-digit PIN. After registration, a normal user-chosen password is used.

The main problem is that the four-digit PIN is too easy to guess: an attacker only has, on average, to try 5000 of them before hitting the right one. You can mitigate this problem by deactivating the PIN code after, say, three wrong attempts for a given GUID; that's the model of smart cards, with your server as the card. However, this will thwart only attackers who do an online brute force.

It unfortunately happens, occasionally, that some attackers obtain a glimpse at some parts of the server database. This is a frequent result of SQL injection attacks, for instance. Discarded old hard disks are also a classic source of such leaks. This is the very reason why you envision storing not passwords of PIN codes, but only hashed versions thereof.

But password hashing, even if done properly, only slows down attackers. If the iteration count is set so high that it takes a full ten seconds of computing for your server to verify a PIN code (and ten seconds are a very long time for a waiting customer), and attacker will "just" need 50000 seconds worth of computation, with the same hardware, to "try" 5000 possible PIN codes. Since the attacker will throw in a couple of multi-core PC, he will probably get down within an hour or two. That's not a lot.

I advise using a longer PIN code, say 8 digits.

To sum up: your GUID is not "secret enough" to tolerate a four-digit PIN, even for a one-time registration page. Using a GUID instead of the email address is interesting and you want it to be as discreet as possible (so use "v4" GUID), but even so, four digits are not enough for a PIN when the verifying system is not a tamper-resistant smart card. Use eight digits (or more). Since the user will type the PIN code only once, he can tolerate a rather long sequence (Microsoft could make users type 25-letter activation keys, so I don't think that 8 digits for registration would be too much to ask).


The PIN is very weak against brute force if an e-mail is compromised, however, this could be partially counteracted by simply putting a lockout after, say, 3 tries. This gives an attacker a 1 in 3,333 chance of breaking in. It's still not very good, but it might be sufficient depending on the level of security you need. I'd also audit how often they get locked out and if you start seeing it locking out a lot, I'd change it because it would show someone is attacking you.

If there is anyway to use a longer temp password, that would certainly be very much preferable, but the lockout is a minimal step that could be used to help render the system a lot more secure than it currently is. (This assumes that the GUIDs are generated in an unpredictable way as well. If GUIDs are predictable, then the lockout is not sufficient as attacks could be made against a large number of GUIDs and attacking 3000 or so to get a success is viable unless GUIDs can't be guessed.)

  • +1 for brute force attacking a large number of users to establish a break. Aug 7, 2013 at 22:19
  1. I find a 4 pin number a bit short when you could just as well use a random generated string which would be harder to guess. Even though a 40 char guid should be ok (make sure that it's properly generated and not predictable)
  2. 40 char GUID seems long enough
  3. Hashing and salting something which can only be a number between 0000 and 9999 is a bit overkill considering it would take minutes to generate all possibilities, even with proper salting.
  4. Looks good, make sure you use PBKDF2, bcrypt or scrypt to salt and store the passwords
  5. Looks good

The one thing you can still do to make this stronger is to add two factor authentication. The two factor authentication can then also be used in conjunction with the initial password configuration.


You need to step back and think about context.

"Is this secure enough?" is an unhelpful question.

"It this secure enough for a bank were a customers life-savings are at stake?" is a good question.

What are you protecting with this system? What kind of balance do you want to achieve between usability and security? If this is a high-security system then requiring the users keep track of a ten-digit PIN makes sense. If you're protecting low-value accounts then 4 digits is probably just fine.

You describe the 4-digit pin as non-unique. You shouldn't really care about uniqueness, you should care about predictability and brute-forcability. Using a strong random number generator will help with predictability, using a longer PIN and having lockouts will help with brute force attacks.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .