How does Authy's 2FA work, if it doesn't connect to the server?

Authy show me secret numbers without any connection with server. How can it do it ?

Authy is using a one-time passcode (OTP) algorithm which come in a number of flavors, the two most popular being HMAC-based OTP (HOTP) and Time-based OTP (TOTP). Authy is using TOTP.

Both algorithms are essentially the same; they require some seed data and a counter to generate the next passcode in the series. HOTP implementations increment the counter each time the user requests/uses a passcode, TOTP increments the counter after a given time interval.

In Authy's case, when the user submits a passcode to the server, the server looks up the user's seed data, calculates the counter value based on the timestamp of the request and then generates the proper passcode. The server then checks that the generated passcode matches the user-submitted passcode.

Is it secure ? Can I know next number if I know N previous numbers ?

Yes and no, it depends on whether or not you trust the server's security.

Given N previous tokens an attacker still shouldn't be able to recover the seed data. However, these algorithms require the server to store the seed data for all of the users. If an attacker is able to compromise the database (through SQL injection, etc.) then they will be able to generate valid passcodes. This is what happened to RSA and their SecurID tokens (http://arstechnica.com/security/2011/06/rsa-finally-comes-clean-securid-is-compromised/)

Some companies like Duo Security (https://www.duosecurity.com/) and Twitter (https://blog.twitter.com/2013/login-verification-on-twitter-for-iphone-and-android) are tackling this issue by implementing challenge-response two-factor authentication with asymmetric key encryption. They only need to store public keys in this case, meaning that if their database is leaked an attacker doesn't have the private keys necessary to generate valid responses.

Disclaimer, I worked at Duo.


Updated based on questions in the comments

The algorithms (HOTP or TOTP) must be the same on the server and the client application?

The algorithm is identical, just the way the counter value is generated is different. If Google were HOTP and Authy wanted to support Google accounts, their app would have to generate and store the counter value differently from TOTP accounts.

Does HOTP client require connection with server to get next passcode (because it doesn't know how much requests was made from last time), while TOTP doesn't require it?

No, HOTP doesn't require a connection to work, but HOTP is generally not used because it's easy for the phone and server to fall out of sync.

Say both the server and app start out with a counter value of 0. The server usually has a window, maybe the next 10 passcodes, that it will consider valid. When the user submits a passcode, the server will compare the submitted passcode with the next 10 generated passcodes. If any of the 10 match, the server can update the stored counter value and remain in sync.

The problem though, is that the user may be able to generate too many passcodes in the app without using them. If the user is able to increment the counter beyond the passcode window size, then the server can no longer verify that the passcodes are valid.


To see in detail how the OTP tokens are generated, see this informative blogpost.