Yesterday, the information security company Trail of Bits announced a new service, called Tidas. The service is intended to make it easy for developers to include a password-free authentication experience in mobile apps on the iOS platform. They’ve provided some sample code and a developer Guide / FAQ, and I’ve spent some time looking at it to try and understand how it works. Here are my first impressions.
NOTE: I haven’t actually looked at the full protocol running “in the wild” yet, so it’s quite possible I haven’t fully grokked the system. Take this with a grain of salt. I’ll try to update any egregious misunderstandings, as I become aware of them.
The heart of the Tidas system is a new feature, introduced in iOS 9, which allows for a public / private keypair to be split on an iOS device, with the private key hidden, inaccessibly, in the Secure Enclave. This feature was described in Session 706: Security and Your Apps at the 2015 WWDC (the relevant content begins about 46 minutes into the presentation, at slide 195). In this usage, the private key is never visible to the application, and can in fact never leave the Secure Enclave, even for device backups. The application can send data to the Secure Enclave, with a request to have it signed by the designated private key. The device prompts the user to authenticate with their fingerprint, and if the fingerprint matches, then the private key signs the data and returns the result to the application.
To enroll, the user must first authenticate somehow with the remote service. If their account already exists, they’ll need to log into the service, using a password, 2-factor login, or whatever other mechanisms the application provides. If this is their first time using the service, then no passwords are necessary and their enrollment is simply part of the onboarding process. The device then creates the public / private key pair (using elliptic curve P-256), and sends the public key to the server, which associates it with the user’s account. Future requests are associated with the user by a separate identifier (userid, for example).
Later, when the user wants to log into the account again, the application creates a new request. The documentation I read didn’t seem to indicate that it uses a challenge / response format, but instead, that the application creates its own message to sign. The application appends the current timestamp to the message, and sends a hash of the (message + timestamp) to the Secure Enclave. The phone then prompts the user for their fingerprint, signs the hash, and returns the signature to the application. The inclusion of the timestamp helps prevent against replay attacks using old authentication requests.
The final message sent to the Tidas server, then, includes basic header information, the new message being signed, a timestamp, the SHA1 hash of (message + timestamp), and the signature of that hash.
The server uses the userid (or other identifying information) to look up the valid user, and validates the signature of the message. Then, the server returns a session token to the application, which allows the user to continue using the app without needing to re-authenticate for every action. The duration of this session token is also left up to the developer.
In practice, the mobile application will likely be communicating with the applciation’s server, which uses middleware components to correctly identify the user and pass the userid and the authentication message to the Tidas service, which then responds with a thumbs-up or thumbs-down for the request.
All in all, I think it’s an interesting system. I very much like the fact that it’s using a full-on public / private key system, and especially that the private key is completely inaccessible to users and attackers alike. This neatly avoids one of the primary problems with other authentication systems: compromise of user credentials when servers are hacked. There’s no password on the server to crack, and no “password equivalent” (like a hash or long-lived secret) that can just be extracted and used by an attacker (no “pass the hash” attack).
I’m a little concerned that the message is self-created, though this does eliminate a client-server round trip. I think it may be wise to set some basic standards, or at least very strong recommendations, for the content and format of that validation message. (It’s also possible that such recommendations exist and I just missed them on my first read-through). The use of the timestamp inside the signature should also help to mitigate this concern. Also, it would be nice if the session token was used more like an OAuth access token, signing each request individually, though I suppose there’s no reason that can’t be implemented at the application level.
There are still other problems that Tidas won’t directly improve: adding the service to existing accounts, enrolling additional devices to the same account, and dealing with a lost device or password, all of which have proven to be weak points in most authentication systems. Finally, this is only available on newer iOS devices with TouchID, though I would expect that it could be supported on other platforms with similar capabilities.
In some ways, Tidas feels similar to the FIDO U2F system, which also utilizes public / private key signatures, but relies on dongles, doesn’t utilize fingerprint verification, and has a more strictly-defined protocol.
I’m excited to see this new service, and hope to see it (and similar systems) move forward.
UPDATE I had a nice chat with one of the authors of Tidas, who clarified that the user’s public key is only sent during initial enrollment, and not for subsequent login requests. A separate userid (not included within the Tidas login blob) is used to associate that signed message with an individual user’s account. I’ve updated the details above to reflect this new information.