Two-factor authentication using hardware tokens to log on to internet banking sites (among other things) is intended to make banking over the Internet more secure. It turns out that it isn’t as great as it seems to be on first blush. Bruce Schneier has talked about this problem several times. Why is this problem so difficult?
Well, it’s subject to a number of attacks and it is hard to defend against these attacks. The type of attacks I’ll discuss here are all variations on the man-in-the-middle (MITM) class of attacks.
For a “regular” phishing attack, the attacker only needs to present a plausible looking logon dialog for the user to enter username and password. Once the attacker has those, he can pop up any kind of error and pretend there are network problems. Now he has the username and password and can empty the user’s bank account at leisure.
Before getting into how we could make it technically very difficult for someone to steal our money from the bank, it’s worth thinking about what the bank could do to detect that someone is actually trying to steal our money. It turns out that there is a lot they could do with current technology to detect abnormal patterns in payment behaviour, but that they aren’t doing. But in what follows, I’m going to go in another direction.
If the bank uses two-factor authentication with hardware tokens, the password the user has entered can’t be used by the attacker to log in himself in a separate session. The password the user generated is dependent on a challenge the bank issued and that is part of the logon dialog the bank presents. Some tokens are also time-based.
The concept of MITM, however, is that the user connects to a fake site set up by the attacker, while the attacker, in the background, connects to the real bank site. The bank sends a challenge to the attacker’s site, which then presents the same challenge to the real user. The real user calculates a password, enters it into the attacker’s web form, which the attacker then uses to log into the bank site. There is no way the real user can detect that this is happening, except by checking which IP number he’s actually talking to. And do you know your bank’s IP numbers by heart? I don’t.
Some of you may protest that this is exactly what SSL is supposed to protect us against, and you’d be right. The problem is that there are ways to defeat that protection, so we can’t count on SSL to protect us anymore.
Ok, so where are we now? Well, the nice and naive user is talking to a MITM who, in turn, is talking to the nice, naive user’s nice and naive bank. Now the user enters one or more account numbers and monetary amounts to pay to those account numbers. The attacker passes that on to the bank, but takes care to change the account numbers to some account he controls. As the bank site puts up a summary of transactions, the attacker takes care to change the contents to look like what the user expected to see.
Before actually posting these transactions, the bank again challenges the user to produce a “digital signature”. Often, this challenge is based on a checksum of account numbers and amounts, so in theory the user could detect that the bank does not have the same list of transactions that the user entered. But, sadly, most of us can’t run MD5 checksums in our heads in realtime, especially if nobody wants to tell us on what it is based. So the user can only sign the checksum and actually authorize another set of transactions than the one he entered.
How can we solve this? Well, one of the following are solutions that could work, at least partially (making it slightly harder for the attacker):
- Send the challenge to the user from the bank using another medium, such as SMS. Curiously, this still doesn’t help much unless the user can see that the challenge actually is based on the transactions he intended. So the SMS must contain a summary of those transactions, severly limiting how many transactions can be viewed in the same SMS.
- Have the user recalculate the challenge based on the transactions he entered. But that algorithm will probably be a script in the page the bank sends out, and the attacker has had the opportunity to modify that page, so you can’t trust the calculation.
- Have a separate program calculate the challenge from the transactions on the user’s machine. If you think about this for a while, you realize that this is exactly what digital signatures are.
The above leads me to conclude that two-factor authentications won’t ever work satisfactorily for authenticating transactions. If you modify them enough to work, you’ve actually implemented digital signatures, so that’s what you should do instead. These systems already exist, so let’s use them.
The one safe way I see of performing these transactions is that the user:
- Creates a list of transactions in user-readable text form
- Calculates and adds a digital signature using a client side program that is able to handle PGP or S/MIME. The user’s private key could be on the computer and password protected, or on a smart card. Best of all is a smart card with the ability to calculate the digital signature on the card, so the private key never leaves the card at all.
- The user sends out the signed text to the bank using the web or email; it really doesn’t matter.
- The bank processes the transactions and sends back a receipt with the results, signed with its own digital signature in the same fashion
- The user can now verify the receipt from the bank and check that the transactions are listed as intended
To make it look less like email and more like hi-tech, all this can be dressed up in a snazzy web page, of course.
2005-07-03: added a paragraph and a link about Paul McGowan’s article