Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm familiar with password hashing, using salts, bcrypt etc.

But it doesn't seem like this would work to store a 4 digit pin code since the attacker could try all 10,000 combinations quite quickly. Is there something I'm missing or how is this commonly done?

share|improve this question
6  
How is the PIN entered: is this an ATM (Automated Teller Machine), a door lock, or something else? How is the PIN verified? What is the transmission channel between the user input and the verification mechanism? –  this.josh Aug 31 '11 at 16:35
    
The PIN is entered over HTTPS in a webpage. (think online banking) –  Brian Armstrong Jan 20 '12 at 19:46

3 Answers 3

up vote 12 down vote accepted

If you are worried about a "leaked database" scenario (rather than the online cracking vector, which can be mitigated by per-user, per-IP, per-site rate-limiting and lockout) then you are right that hashing is not enough.

Even using the most complex sequence of hashes & salting e.g. bcrypt(pbkdf2(sha256(pin),salt1),salt2) you are still going to be vulnerable to anyone who can see (e.g. from a source code/docs leak) what algorithms are used and who can find your salts (normally stored in the same DB/table) -- they can just run the same series of hashes, and even if it takes a minute for each that's only 7 days to try them all. So you would basically be relying on security-by-obscurity.

In this case it would be worth encrypting the password hashes with a secret key (which can be kept separately from the source code, only accessible to trusted "production security operations" users, never re-used in pre-prod environments, changed regularly, etc.). That secret key will need to be present on the server which validates/updates PIN codes, but it can be kept separately from the user/pin database (e.g. in an encrypted config file), which means that Little Bobby Tables won't automatically get access to it when he snarfs the whole of T_USERS via SQL injection, or when someone grabs a DVD with a DB backup on it from your sysadmin's desk.

[Normally encrypting the hashes is not recommended, because its better to use a secure hash, good salt and strong password/phrases, and encrypting the hashes can give a false sense of security. But if you can't have strong passwords then there aren't many other options -- beggars can't be choosers...]

You could combine the PIN with a password -- but in that case why bother with the PIN at all? Just require a strong alphanumeric password. (If the PIN is used in combination with a smartcard or token or similar, of course, then it can add to the overall security.)

We could use a bigger (6/8 digit) PIN. Its not feasible to make a digit-only PIN be secure from brute force: at 1B hashes per second, we'd need 16 or more digits to push the brute force time beyond a year. But adding a few more digits might be enough to make the online attack easier to detect and block -- with only 10K combinations its going to be hard to set "slow-force" thresholds low enough to make an attack infeasible. Unfortunately, you have likely have physical constraints (hardware selection) which preclude longer PINs.

share|improve this answer
2  
Thanks this best answers it I think, since I was mainly wondering about the scenario where the database is compromised. I think keeping a secret key separate from the main database, using this to salt the pin hash, and only sharing it with key employees makes the most sense. This way getting access to the db wouldn't be sufficient, they'd need to hack the server also. Thanks! –  Brian Armstrong Sep 3 '11 at 20:14

The two common things that limit this type of attack are:

  • for sensitive applications the PIN is in often addition to a password
  • brute forcing is disallowed, usually by a lockout after 3 or 5 tries. Sometimes the input device also enforces slow entry of the PIN in addition to lockout, as a further defense.
share|improve this answer
4  
Slow entry is usually combined with the lockout - I should have written that explicitly. –  Rory Alsop Aug 31 '11 at 7:30
2  
Also, if you are able to enumerate enough users (say 10.000), you can try one static random pin for all users, and you most probably would find an account. And, since you only tried once per user, no lockout would happen! Also see: security.stackexchange.com/questions/6694/… –  Dog eat cat world Aug 31 '11 at 7:32
2  
Hence the 1st common thing - it is often used in addition to a password:-) –  Rory Alsop Aug 31 '11 at 7:36
3  
@Dog eat cat world: "since you only tried once per user, no lockout" - I disagree. The system should detect that someone has made a lot of attempts from a given location (e.g. from one PIN pad/terminal/network address/what-have-you) and react accordingly (lockout the location, trigger a warning to system operators, etc.). As you've shown, only associating lockouts with users is a security vulnerability. –  Piskvor Aug 31 '11 at 9:35
2  
@Dog eat cat world: actually fewer than 10k users: it's like the birthday problem only you care whether someone has the same PIN as you chose, not the same PIN as anyone else. I think you'd hit 50% chance of success after <7k users. –  user185 Aug 31 '11 at 13:14

Password hashing schemes such as bcrypt are meant to give some security in the following context: the attacker can read whatever information you store to verify the password (e.g. he gets a dump of the database through a SQL injection attack). With a 4-digit PIN, entropy is too low to provide much resistance in this situation, even with huge salts and iteration counts of biblical magnitude. Therefore, if you use a 4-digit PIN, then you already assume that the attacker cannot access the password verification information, in which case you can simply store PINs "as is".

Even if the attacker must go through the normal authentication process for each guess (that's an online dictionary attack: for each guess, the attacker must interact with either the user or the server, or both), 10000 possible PINs are a very low figure. So proper security can be achieved only by enforcing arbitrary delays -- the extreme case being what smartcards usually do, i.e. lock themselves out after three wrong PINs (a locked smartcard is like an infinite delay). This is delicate with networked services, because you do not want people to be able to lock at will other people's accounts.

share|improve this answer
2  
Your analysis in para 1 seems to assume that an attacker who "gets a dump the database" has access to everything on the server which is used to verify the PIN. SQL injection and priv-escalation vulns are quite distinct (and its probably rare for SQL injection to be bad enough to provide a platform for OS-level priv escalation), which makes this untrue in general, I think. –  Misha Aug 31 '11 at 11:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.