Services/Sync/KeyRecovery

From MozillaWiki
< Services‎ | Sync
Revision as of 03:55, 22 September 2011 by Rfkelly (talk | contribs)
Jump to navigation Jump to search
Draft-template-image.png THIS PAGE IS A WORKING DRAFT Pencil-emoji U270F-gray.png
The page may be difficult to navigate, and some information on its subject might be incomplete and/or evolving rapidly.
If you have any questions or ideas, please add them as a new topic on the discussion page.

Goal

To securely allow a user to recover their sync key, using only the username and password for their Mozilla Services account.

Overview

Currently the sync key is never stored on Mozilla servers in any form; it only exists locally on each device connected to the sync account, plus in any backups explicitly made by users. This provides some additional security for their sync data above that provided by their account password.

However, if the user accidentally deletes or loses their sync key, they permanently lose access to the sync data stored on Mozilla servers. Currently their only option is to discard all sync data and start again with a new key.

If the user *opts in* to the key recovery service then their sync key will be encrypted and stored on Mozilla servers, where it can be recovered using their account username and password. They may also use this service to obtain the sync key when setting up a new device, rather than using the current J-PAKE scheme to transfer it from an existing device.

The client will use the user's account username and password to encrypt the sync key prior to transmission to the service. Barring our deliberate snooping or cracking of the user's password, this means that the sync key cannot be read by Mozilla.

If the user forgets or resets their password then the stored sync key will be unreadable and must be re-stored from a connected device. This is a feature - even if an attacker compromises their email and resets their password to gain control of their account, the attacker will not gain access their existing sync data.

Since this scheme reduces the security of all the user's sync data to the security of their account password, it will be a completely opt-in service and will be disabled by default.

The encrypted sync key represents a particularly high-value target for an attacker, because:

  • it potentially allows access to *all* of the user's sync data, and
  • it will be encrypted using a relatively low-entropy key (the user's account password)

We therefore entrust its storage to a separate service from the main sync-storage service, so that it can be run from a high-security server.

Details

Naming

In initial discussions we've been calling this a "key escrow service", but to me (rfkelly) that conjures up too many big-brother clipper-chip-style associations. Since the idea is that Mozilla won't be able to obtain your sync key even if you enable this service, I think "key recovery service" has more accurate connotations. Thoughts?

Key Encryption

Before uploading to the service, the client encrypts the sync key using its existing standard encryption routines. The encryption key is derived from the username and password using PBKDF2. Details follow.

To encrypt the sync key for storage in the recovery service, the client uses PBKDF2 to derive an appropriate encryption key from the user's account username and password:

   salt = get_random_bytes(16)
   enc_key = PBKDF2(username + password, salt, 4096, 32)

This is then used to encrypt the sync key via AES-256, with a random IV and HMAC256:

   IV = get_random_bytes(32)
   ciphertext = AES-256(enc_key, IV, sync_ke)
   hmac = HMAC256(enc_key, ciphertext)

The details necessary to decrypt the sync key are serialized into a JSON structure, which is sent to the key recovery service for storage:

   { 
     //  Parameters for key derivation, as used by deriveKeyFromPassphrase
     "salt":  "b64-encoded salt",
    
     //  Encrypted payload, same format as CryptoWrapper WBO output
     "ciphertext": "b64-encoded ciphertext",
     "IV": "b64-encoded IV",
     "hmac": "hex-encoded hmac",
   }


Open questions:

  • is there something better than PBKDF2 for this purpose?
  • should be include the number of iterations in the stored PBKDF2 parameters? Someday we might want to increase it.
  • should we mix the HMAC_INPUT string into the PBKDF2 inputs?

Server Protocol

Since the server component is intended to run from a high-security restricted-access environment, it is designed to be as simple and light-weight as possible. In particular, it will offload responsibility for authentication to a separate service.

Client Protocol

Authentication

Server-Provided Tokens

User-Provided Tokens