Two-factor authentication (also “two-step verification”) is, in short, when authentication involves two stages - quite often some sort of one-time password (OTP) in addition to your regular password (video). Online banking has been using this for quite some time, and lately the method has also been gaining popularity all over the net.
There are other methods available, but time-based one-time passwords (TOTP) are quite commonly used. Several mobile apps support the standard, Google Authenticator being one (Android, iOS).
At the end of this article, there is an example Vaadin application that works with these apps.
An algorithm for time-based one-time passwords, TOTP, is defined in RFC 6238. It is based on the HMAC-based one-time password algorithm (HOTP, RFC 4226), essentially using time instead of a counter. In short, the service and the user have a shared secret key, and given this key, an app or hardware device (known as a token) will display a new password every 30 seconds. Convenient, and since it is only valid for a short while, there is less chance that someone looking over your shoulder can use your password later.
Note that the shared secret key used to set this up IS secret, and should be treated as a password.
Before implementing TOTP in your applications, it is a good idea to read through the RFC, and especially pay attention to the recommendations. Also take usability considerations into account (some are listed later).
To set up TOTP for a user, you need to
Generate a secret key for the user, and save that key
Give the secret key to the user, e.g via QR code (always use HTTPS) or snail-mail
Make sure the user has everything set up correctly (i.e check one password before enabling)
Ask for the TOTP password when appropriate, verify using the secret key
Adding security is often a balance - if you make it too complicated and annoying, the users will find a way to circumvent your security measures, which will result in reduced instead of increased security. When done properly, TOTP is easy to set up and use - but it might also be something new and unfamiliar to many users, so care should be taken to make the process as easy and understandable as possible.
Make the process to enable TOTP easy to follow, and guide the user through it.
Use clear language without terminology (don’t say things like “TOTP” and “RFC 6238”).
Before enabling TOTP for the account, make sure the user has everything set up correctly and is able to use it, by requiring the user to enter a TOTP password.
Set up a process to recover the account if the user accidentally loses the secret key (phones get lost…) This process must have the appropriate security measures in itself.
Starting the app and entering the password takes time; only ask for the TOTP password when appropriate. For some critical services this might mean at every login, but for most services it’s better to identify critical functionality that benefits from extra protection, while allowing the user to operate without the password most of the time.
Your setup is more secure if the server only allows one verification within each 30 second timeslot, so that the password is really ‘one-time’. The downside is that the user can only do one verification (e.g login) every 30 seconds.
TOTP requires the server and the user (app) to have the same time. Because of network latency and differences in the time on devices, multiple 30-second timeslots are usually checked to avoid problems. The number of timeslots checked is a tradeoff between usability and security.
This is not rocket surgery, but if you do not feel comfortable with the concepts, you might still want to consult with an expert.
Heartbleed (and such)
Two-factor authentication does not make attacks like Heartbleed harmless, since the attacker is able to listen to your network traffic, and in many cases hijack your session. Also, if the system was vulnerable when you set up two-factor authentication, there is a good chance that the attacker has your secret key, rendering TOTP useless.
However, provided the secret key is not compromised, two-factor authentication can limit the immediate damage. It can prevent the attacker from changing passwords and performing other critical operations. It can also stop him from logging in himself, after your session has ended.
With any luck, TOTP could buy just enough time to fix the vulnerability before significant damage is done.
To minimize the risk of compromising the secret key, it can be given to the user via a separate channel - e.g snail-mail, or having the user pick it up in person.
TOTP and Vaadin
To use TOTP in your Vaadin application, you can use the GoogleAuth TOTP library as shown below. It is published under liberal BSD license. There are other TOTP implementations available, and the RFC contains a (somewhat messy) reference implementation.
To create a new shared secret key:
GoogleAuthenticator gAuth = new GoogleAuthenticator();
GoogleAuthenticatorKey key = gAuth.createCredentials();
A QR code that GoogleAuthenticator is able to read is generated using the QRCode add-on by John Ahlroos:
URI keyUri = new URI("otpauth", "totp", "/" + issuer + ":" + account,
"secret=" + secret + "&issuer=" + issuer, null);
QRCode qr = new QRCode(“QR code”, keyUri.toASCIIString());
Finally, the one-time password entered by the user can be verified as follows:
boolean correct = gAuth.authorize(key.getKey(), enteredPassword);
Once authorized, you might want to prevent the user from using the same password immediately again. This will make the password truly ‘one time’.
Check out the full example from GitHub