Is "type letters 1 4 and 7 of your password" considered secure?
March 28, 2013 6:13 AM   Subscribe

Instead of the usual "username/password" challenge, some bank websites ask you for a username, and then for some letters from your password -- e.g. 'Type letters 1, 4 and 7 of your password'. I understand that the advantage of this is that you never enter your whole password, thereby making life difficult for keyloggers. But I don't see how it's possible to implement such a system without (effectively) storing the password in plain text on the server, which surely not a good idea. What is this practice called? Do security experts consider it good practice? Can you point me to a paper that explains how it is implemented securely?
posted by beniamino to Computers & Internet (34 answers total) 11 users marked this as a favorite
Your'e correct: the password is stored in some sort of plaintext on the server (if it were hashed, no one would be able to figure out specific characters in specific positions on the password). This is terrible practice, as a server breach will expose all passwords without effort.

I don't know if there's a particular name for this sort of thing, beyond noting that it may be some sort of home brewed crap that someone, who is more clever than smart, came up with.
posted by chengjih at 6:24 AM on March 28, 2013 [2 favorites]

Yes, the slightly-better way for them to do it would be to pick a bunch of allowable combinations of password characters and hash those (e.g. hash char1+char3+char7, char2+char5+char9, ...).

It's only slightly better than storing it in plaintext, because a rainbow table attack against a _three character_ hash shouldn't be hard at all.
posted by katrielalex at 6:27 AM on March 28, 2013 [2 favorites]

You could just hash characters 1,4, and 7 of your password upon creation, but this still seems pretty insecure, since rainbow tables have long been created for every three character password. Salting would make it more secure, but still it would not be very good.
posted by rockindata at 6:27 AM on March 28, 2013 [1 favorite]

So this seems like a really shitty version of a challenge/response protocol. Challenge/response protocols are commonly used in authentication to prevent replay attacks, but it is hard to find one that a human can implement since most require some math. So you either give the human a dongle and have them type in a number or you do something like this which as everyone else aptly points out is extremely insecure.

There are however better human challenge/response protocols in the literature: here is one for instance.
posted by goingonit at 6:44 AM on March 28, 2013

I just file it under "idiotic bank security practices", along with things such as "your password cannot be more than 12 characters" and "if you ever forget your password, just tell us your mother's maiden name or some other easily found personal information, and we'll reset it for you".

Which of course is why your mother should have a different maiden name for each online service, and that maiden name should be something like "fhopquLdgTRR34".

This becomes hilarious when they ask for it over the phone.

posted by pont at 6:44 AM on March 28, 2013 [21 favorites]

Your'e correct: the password is stored in some sort of plaintext on the server (if it were hashed, no one would be able to figure out specific characters in specific positions on the password). This is terrible practice, as a server breach will expose all passwords without effort.

Not in the systems like this that I've built.

Passwords are stored both seeded and hashed. Then the function doing the checking decrypts on the fly in memory before checking. In very simplified psuedo-code:

function checkPasswordDigits(username, password, digitstocheck){

1. get password hash from db based on username

2. dehash and seed, and create a local variable (so not available to anything outside the instance of that function call) containing the result of that

3. Check the necessary digits

4. return a boolean yes/no result


That's oversimplified obviously, but its not complex, and doesn't expose anything at any point. More importantly it means you can randomly (or pseudo-randomly if you're really worried about keylogging) change the digits you ask for on each request.

Frankly if you're at the point where someone is so far into your server that they can sit there and watch the above happen in memory then you've got far bigger problems to worry about.

Unless you're having to deal with millions of logins at the same time, the memory overhead isn't prohibitive either (and again, frankly if you're dealing with millions of logins you'll be worrying about memory overhead long before this little function causes you problems).
posted by garius at 6:46 AM on March 28, 2013

I work in e-commerce, although not in banking, and as noted above, it doesn't sound like a good idea.

Banks, especially the smaller banks that I otherwise favor for their generally better customer service, etc., seem to be at a kind of sophomoric level of understanding of IT security. There is arguably no worse thing that could happen than a breach at a bank in terms of the info that bad guys could get at that could complicate your life for a long time, and yet I've seen a lot of bank login security problems and gimmicks. I visualize a lot of mid-level managers with no idea about IT security supervising a lot of second-string IT guys as they cobble together things that will let Mom and Dad feel good about their account security. "Hey! Isn't that clever!" Sites that will put you through all kinds of hoops and make you call the office during business hours if you fat-finger a password with high complexity requirements, but yet you're entering the p/w on a non-encrypted page or when you call the bank all you have to do is give them the last four of your social and then they'll reset your password.
posted by randomkeystrike at 6:47 AM on March 28, 2013 [1 favorite]

The password does not necessarily need to be stored in clear text on the server. I work with software that stores 2-way encrypted passwords as a tuple of an index into the application's key store, and the encrypted password value. That way, when an occassion like this occurs, an internal procedure can dynamically recover the plain text by processing the encrypted string with the referenced key.
posted by hwestiii at 6:48 AM on March 28, 2013 [1 favorite]

Garius -- if you can dehash, you're doing it wrong. We call this "encryption" rather than "hashing" and it just pushes the attack down one level to acquiring the password encryption key (which has to exist somewhere in your system in plaintext of course).
posted by goingonit at 6:50 AM on March 28, 2013 [12 favorites]

The thing with security, is that it's not an absolute - you have to consider the attack surface you are mitigating.

So the question becomes, not "is storing the password in a reversable fashion on the bank side insecure", but "will the security advantages of asking for only part of the password outweigh the disadvantages of storing it server side" - Which is, fundamentally, about the danger of an attacker gaining the hashes, verses an attacker compromising a users system and installing a keylogger.

There is a bunch of reasons that question is not that simple either - obviously, an attacker would obtain all of the hashes, which would be of course quite reversable if you knew that they only required three letters.

Of course, for an eight character password,there could be up to 336 hashes per user to store, but also 336 hashes per user to break - and, of course, you do not know in advance which one is going to be requested, so you have to pre-break all of them (with appropriate salting, rainbow tables could be made less effective - this, of course, assumes they got their crypto right! A 40bit salt increases your table size by a factor of four billion entries - for three chars of password (digits and letters only - 36 entry keyspace), this means a total of 46656 passwords, yet requiring a table of 373TB. Almost all rainbow tables rely on NO salting.

Of course, if you have the hashes and wish to target a single user, you only need attempt around fifteen million passwords. This assumes, however, that there is no OTHER information in the hash - a reasonably flawed assumption. As an implentation example, lets say my password was "elephant" (because I like elephants!). Assuming that this is the ONLY secret not known to the attacker (who has the hash), lets we create a hash for each combination of password+3 letters, so the first one would be 'elephantele', the next hash would be 'elephantelp', and so on until you hit 'elephantant'.

An attacker now has to attempt 947 trillion passwords against this hash (ignoring dictionary attacks, of course - but we're just talking about pure hash strength here, not seperate password strength) for our theoretical letters+numbers keyspace. Assuming, of course, they know the password is only eight chars long. A strong hashing algorythm should be kept busy until heatdeath at this point.

There are ways to strengthen this even further, of course - for example, by adding information about the user which is NOT stored in the same database to the hash. But I discount these, since an attacker who has the hash database also has full run of the bank separately, and can obtain this information. (Assuming they know HOW the hash is constructed, but one should assume that we have no secrets from the attacker who has already penetrated our organisation!)

But, lets say there is a breakthrough, and it is not. The attacker is STILL less likely to have the hashes, than to have broken your computer and installed a keylogger, due to the difficulty of breaking into a bank to obtain said hashes vs malware on your PC. Additionally, a bank is far more likely to know if they have been broken into, and take action based upon this.
posted by jaymzjulian at 6:57 AM on March 28, 2013 [4 favorites]

I'm guessing wildly because like most here I am not a security expert but what if each letter was encrypted separately, using something like account creation timestamp as a seed? What you would then do is encrypt each given letter and then compare against the stored versions. No plaintext required. EDIT: only a limited number of input characters so could brure force it if you had stolen the password database. Ignore me.
posted by epo at 6:58 AM on March 28, 2013

Yes - sorry, I was playing a bit loose with terminology there in an effort to keep the explanation layman-friendly, and was slightly annoyed with the suggestion that such a system automatically meant there were plaintext passwords being stored (and flying around) everywhere.

My point was that the presence of the digit system doesn't automatically mean you're storing the password in plaintext anywhere. Just that you've got it in a decryptable format.

As goingonit rightly points out, if you're doing that it means you've then got an encryption key somewhere - and then you need to address the security of that. But it doesn't mean that a system using that methodology is one rainbow table away from compromise - which was the implication that seemed to be coming out of the previous posts.
posted by garius at 7:00 AM on March 28, 2013

My bank asks for a username and password and then asks for three characters from a memorable phrase (not the same as the password).
posted by atrazine at 7:04 AM on March 28, 2013

(Oh, btw, on salting: for those who are unaware, how salting works, is to add something KNOWN to the password in order to defeat rainbow tables - this is a technique that is as old as computers themselves (the unix crypt from the early 1970s implements it, as an example. So if my password hash has was 'abc$xyzzy', then you would hash 'abc+password' to match 'xyzzy' rather than just hashing 'password' to match the hash. So yes, the attacker knows the salt value - but each users salt is different, so they can no longer just build a table against all possible passwords without also building it against all possible salts)
posted by jaymzjulian at 7:04 AM on March 28, 2013 [1 favorite]

Oh, oblig wikipedia: - particularly, talks about a clever hash based implementation
posted by jaymzjulian at 7:10 AM on March 28, 2013 [1 favorite]

There's a lot of really, really bad info in this thread. The long and short of it is:

- It is possible to do this in a method that would be considered "secure" under US banking regulations. I cannot speak to other countries' regs.
- The security of the system would be significantly less than that of a system that only stored a salted and hashed password.
- It is highly unlikely that this bank is trailblazing and doing this the right way.

Troy Hunt pretty much eviscerated Tesco over what this bank is likely doing.

To address some other misinformation: rainbow tables are not generally used to attack salted hashes, so let's throw those out. Salts do not protect against brute force attacks (n.b., I disagree slightly with the linked page -- salt length can very much impact the security of your hash, but if someone gets the salt it's certainly game over).

If the password table is compromised on this bank's site, and if they are hashing subsets of the characters to do it securely, and even if they're using bcrypt as in the second link with a high work factor, 3 characters will take minutes to crack.

In practice, what they're doing does not provide effective security. Unless they're the first organization on the planet to implement homomorphic encryption, this is pretty broken.

And garius? If you're building systems that encrypt passwords rather than hashing them, you really need to spend some time reading the literature on security engineering from 10-15 years ago. There's more to security than just confidentiality.
posted by bfranklin at 7:20 AM on March 28, 2013 [11 favorites]

If only from internal attackers who now have passwords to other systems because so many people recycle the same password over and over again.
posted by Mitheral at 7:33 AM on March 28, 2013 [1 favorite]

To be honest, I don't build such systems anymore - and haven't for about that amount of time.

Agree that on that basis I should probably have stayed out of it. Unfortunately the "must be plain text then" just pushed one of my buttons and so I instinct posted - which is always a mistake. will now sit back and enjoy the answers that are far better than mine!
posted by garius at 7:36 AM on March 28, 2013 [1 favorite]

Quite a few years I used to work with some very good security professionals and think I can distinguish between knowledge and hand-wavy jargon spouting.

People who admit to being ignorant on this subject should take note of jaymzjulian, he probably knows what he is talking about (or is a high class bluffer). Some others are just recycling snippets they part understand or are throwing rocks at a hypothetical implementation which just happens to be conveniently easy to throw rocks at.

Individual banks may do it badly but in the context of an overall system design, partial passwords provide a reasonable tradeoff between user friendliness and security against the most likely risks (shoulder surfing, key loggers, being overheard). My bank (First Direct) uses partial passwords for both web and telephone authentication but (crucially) combine it with other shared secrets.
posted by epo at 8:08 AM on March 28, 2013

Okay, I'll freely admit that I have no idea what I'm doing here, and also I don't implement any web systems, so my half-baked idle musings aren't going to come back to bite anyone ... but: don't some hashes have the property that hash(a, b, c) = hash(hash(a,b), c) ?

If so, for a password of length N (one of my banks enforces N=8; no more, no less), couldn't you store:

secret[1]=hash(salt, 1, password_char[1])
secret[2]=hash(salt, 2, password_char[2])
secret[N]=hash(salt, N, password_char[N])

then ask the user for the Xth, Yth and Zth character of their password, you'd have a match if

hash(secret[X], secret[Y], secret[Z]) = hash(salt, X, password_char[X], salt, Y, password_char[Y], salt, Z, password_char[Z])


Please ignore and file under hand-wavy jargon spouting if this is not a thing.
posted by scruss at 8:16 AM on March 28, 2013

scruss: I'll spare you a derivation, but a hash with property hash(a, b, c) = hash(hash(a,b), c) would not be a cryptographically secure hash. You, by definition of the property, have collisions that permit tampering.

epo: Partial passwords combined with other mechanisms possibly add security, but partial passwords in-and-of themselves offer less security than the comparable password. You're trading nominal defense against a key logger for less defense against brute force attack. Further, passwords in the context of a bank aren't for the user's protection; they're for the bank's protection.
posted by bfranklin at 8:27 AM on March 28, 2013 [2 favorites]

> ... would not be a cryptographically secure hash

Thank you! I knew that there was something too simple about that. I think I was misremembering half of HMAC somewhere.
posted by scruss at 8:42 AM on March 28, 2013

While I'm not smart enough to add anything to this discussion, the people at the Security Stack Exchange generally are. They have a little more information.
posted by Folk at 9:14 AM on March 28, 2013

- It is possible to do this in a method that would be considered "secure" under US banking regulations.

Can anyone explain what the benefit of this method is for the banks? It seems like it's just adding complexity without adding security.
posted by no regrets, coyote at 9:48 AM on March 28, 2013

Can anyone explain what the benefit of this method is for the banks? It seems like it's just adding complexity without adding security.

I went digging for some actual cryptanalysis on partial passwords, as I've never done the math on them myself. This NewScientist article would appear to confirm my suspicions that partial passwords don't offer a significant security gain. I don't have an IEEE membership so I can't grab the original paper.

Ultimately, it sounds like someone implemented something that looked cool in cryptography without it being fully vetted by cryptographers. I'm guessing these banks are trying to implement something to meet an enhanced control in a regulation so as to improve their risk position under audit. Auditors are not cryptographers, and until papers come out showing that a technique doesn't increase security, it will often be accepted as meeting a control.

My business regularly vets our business partners, asking them for a SOC II or SAS 70 audit report. It's very important to not just look for the auditor's stamp, but also to review the actual selected controls and see if they make sense. There are a lot of games that can be played with scoping audits and control selection to make things look better than they are. As an example, we recently had a potential partner send us an audit report that looked great on the surface, but upon inspecting the controls they were all administrative, and the only technical control in place was a firewall. Not good when dealing with sensitive data.
posted by bfranklin at 10:30 AM on March 28, 2013 [1 favorite]

> Can anyone explain what the benefit of this method is for the banks?

It gives the illusion of security, to make customers feel better; aka "Security Theater".
posted by dirm at 10:33 AM on March 28, 2013 [2 favorites]

Perhaps my reasoning is completely wrong, but I think that it is possible to implement these partial password schemes without storing the plaintext on the server using a secret sharing algorithm, with the additional restriction that the program always asks for specific secrets. For instance, the server could store the value of a second-degree polynomial at x = 0, while you know its values at x = 1, 2, …, 5. During the authentication process, it asks you for three y values, computes the coefficients of the polynomial and checks whether its value at x = 0 is equal to what is stored in the database. No encryption or hashing needed.
posted by wachhundfisch at 11:58 AM on March 28, 2013

The suggested scheme obviously doesn’t offer any extra protection against keyloggers since an attacker could just compute all parts of your password from any three, but I’m confident that an actual cryptographer could easily come up with something better.
posted by wachhundfisch at 12:05 PM on March 28, 2013

wachhundfish, I think you're right -- the paper I link to above gives an example of an actual cryptographer's human-feasible secret sharing challenge-response algorithm.

But yeah, you could also use secret sharing for the split-password scheme rather than store the password in plaintext. Then this is stronger than just typing in the password against both eavesdroppers and break-ins on the server.
posted by goingonit at 12:10 PM on March 28, 2013

The thing that keeps getting glossed over is that, even assuming that the authentication mechanism is completely secure via shared secret or partial password implementations, you've reduced a large keyspace to a small keyspace for authentication.

That is, you've eliminated brute force attacks against the keyspace for the entire password in favor of brute force attacks against a subset of the keyspace for the password.
posted by bfranklin at 12:40 PM on March 28, 2013

It's not a viable attack method.

Suffice to say, a wise attacker would generally not try to brute force something through the standard web-based login interface. Not working for one attack vector does not render it unusable as an attack method.
posted by bfranklin at 5:01 PM on March 28, 2013

This is a fascinating question. I'm no crypto expert (or even a crypto amateur), but perhaps one detail worth noting is that if your bank account is hacked, I would presume that the bank will not hold you liable for the losses (much like how if your credit card is lost or stolen, you are not liable for unauthorized charges).

For that reason, partial passwords seem to offer a stronger protection against keyloggers and a weaker protection against someone who has obtained the password hash. Perhaps the bank (whether naively or not) is betting that a keylogger is the greater threat. The bank has no control over whether you open cool_cat_picture.jpg.exe which subsequently installs a keylogger. A bank ought to (again, perhaps naively) have good enough security that their password hashes can't be stolen in the first place. So, the bank is protecting themselves against password compromises they can't control moreso than against password compromises they can.
posted by wondercow at 5:26 PM on March 28, 2013

My bank used to do that and stopped, probably because it was dumb. In addition to only the certain letters of it, you also had to click the letter rather than type it.
posted by AppleTurnover at 11:12 PM on March 28, 2013

If you have to only enter 3 characters from the set [a-zA-Z0-9] to authenticate, then there is a ~1/250k chance of a 'random' password sufficing to log in, much less than if you used a space of 8-character passwords from the same set of letters.

If you ever keylogged one three-letter password taken from an 8-char password with no repeated letters then you have a 1/336 chance of logging in with it in a future session (i.e., the chance that you get the same challenge); if they're also taken in sequence then you've got a 1/56 chance.

If you follow the algorithm from "smartarchitects" you will see that anyone with the K (or h(K)) and Ri values from the database could do a mere 250k evaluations of a polynomial in order to find a required 3-letter subpassword (all the 250k possibilities from the first brute-force attack); after that, it's only an additional 62 polynomial evaluations to reover each subsequent character of the password.

In summary, this is a dumb scheme which appears to store the password in a much weaker form than a properly salted and hashed password.
posted by jepler at 4:12 PM on March 29, 2013

« Older please recommend the right storage solution (mac...   |   What type of software do I need to accomplish this... Newer »
This thread is closed to new comments.