Interact Security

8/15/2013

When I started work on Interact I thought I'd just need to encrypt a couple of fields in a database. Thinking it through a little more that started to seem a little naïve. Actually building it and getting the security protocols right turned out to be really hard work.

My objective is to mitigate primarily two threats - information disclosure, and denial of service. Consequently, these are the security design goals I set out:

  1. Interact should use, but not rely on transport-layer security (SSL/TLS)
  2. Users must be able to remain anonymous
  3. Authentication (login) should work both with and without an Internet connection
  4. Interact should be resilient to the loss of a synchronisation server
  5. Interact should use client-side encryption

Secure Comms

SSL/TLS is showing it's age[1], so I want Interact to use application-level transport encryption that mitigates the risk of information disclosure through known or unknown vulnerabilities in SSL. Here's a trivialised example of how not relying on SSL might work:

    A → S: KA(PUB)
    S → A: KS(PUB)
    A → S: {KAS}KS(PUB), {M}KAS
    S → A: {KSA}KA(PUB), {R}KSA
  1. When the Interact client A is started, it generates an asymmetric key-pair, and sends the public portion KA(PUB) to the server S, and requests a public key from the server.
  2. The server responds by creating a public/private key pair for the client, and returning the public portion of that key-pair KS(PUB) back to the client.
  3. The client uses the server's public key to encrypt a symmetric key KAS, which in turn is used to encrypt the message M being sent to the server. The server can now decrypt the shared symmetric key KAS with the private key KS(PRV), and finally use the shared key to decrypt the contents of message M.
  4. In the last step a result R is returned to the client, using the inverse of the process described in the previous step. R is encrypted with shared key KSA, which in turn is encrypted using the client's public key KA(PUB). The client decrypts the shared key using KA(PRV), and uses the shared key to decrypt result R.

All of that works independently of how user data is encrypted, but more on that below.

[Edit, April 2014] When I first wrote this section I felt a bit stupid, thinking I was overdoing it. Heartbleed (ref. below) has just been discovered.

Registration and Login

Now that we have secure comms, we can look at user registration and login. Registration (shown below) is as you'd expect. The user provides the minimum amount of information required - a user name and a password. As per standard practice, the password is entered twice to confirm correctness. The user can choose any name, as long as it's unique. The maximum number of characters allowed for both user names and passwords is 500.

Windows Desktop     Windows Phone
Login Registration

User registration requires a working network connection to at least one server, because of the unique user name constraint. If Interact is unable to connect to a server, it will not proceed.

Login is similarly straight forward. Interact remembers the last user name that was used to register or login with, and prompts the user for a password. If a working network connection exists, the user account will be verified remotely, and authenticated locally. If there are no comms account verification is skipped, and authentication proceeds on the client, as before.

Windows Desktop     Windows Phone
Login Login

Server Availability

Interact was designed to withstand the loss of a sync server. Availability is important, and eventual consistency is good enough. Consequenctly, if one server goes offline another should pick up the load. For this to work, servers are distributed, sync content to each other, and clients know about all currently-avaialable sync servers. Additional server endpoints can be added on the client. Because accessing a server in one location might be quicker than another, the user might select a preferred (or default) server if he or she so choses. The Windows Phone UI looks like this:

Select server

The user taps the server icon on the registration/login pop-up's application bar, and the UI changes by including a drop-down list of avaialble servers. The default item in the list is either the first server, or the server designated as the default server by the user.

If the user wants to change the default server, manually add a new server, or modify an existing one, he or she taps the icon next to the drop-down list, from where these changes can be made:

Server list    Edit server

The corresponding Windows desktop client screenshots look like this:

Login

Select a server

Login

Modify an existing server

Encryption

Interact is designed to mitigate the risk of information disclosure. This is achieved by generating a strong symmetric password on the client, which is not known to the server, and is used to encrypt all data stored in Interact on the client and the server. Encrypted data that is uploaded to sync servers cannot be decrypted by the server because servers don't have access to keys.

Client-side, data-level encryption allows sync-servers to operate as zero-knowledge service providers, offering a higher degree of privacy. Client-side encryption also mitigates some of the vulnerabilities in web-based password managers like LastPass and PasswordBox [2].

In conclusion then, data at rest is protected using client-side encryption. Data in transit benefits both from the application-level encryption scheme described above, as well as SSL/TLS. Interact now has three levels of encryption:

Encryption layers

Getting the application-level protocol right, and making it work with authentication and data-level encryption took a long time (there's more that I didn't cover in this post, like timestamps and signing). Another thing I learnt was that just sending bytes to the server (encoded as TLV) made things a lot easier than using JSON[3] - I got to a point where encoding and decoding messages just needed to get out of the way. The solution I have will do for now, but I've spotted areas where I can make improvements. Making this work was fun.

[1] SSL Vulnerabilities and Exploits

[2] Web-Based Password Manager Vulnerabilities, Exploits and Mitigations

[3] JSON and TLV

JSON is easy to use - if you're using your own, or a third-party library that does the work for you. A substantial part of Interact is about security, so I don't use third-party libaries I haven't assessed. I don't have my own JSON library, and I haven't the time to look at existing ones. TLV is a lot easier to implement than JSON, and so that's what I'm using. TLV has other benefits too, which I describe here.

More information


Home | Blog | Photos | Contact | About

Wittenburg.co.uk and all content copyright 1995-2017 by Michael Wittenburg, unless otherwise stated.
All content on this site is licensed under the Creative Commons license, unless otherwise stated.