Data

Agile Keychain design

In the very beginning, 1Password proudly used the macOS Keychain to store all of its information. Written by Apple, this is a fantastic component of macOS and a shining example of why developing for the Mac is a joy. After years of use, we learned a lot about the nuances of the macOS Keychain and how people benefited from it, as well as where things could be improved.

Why did 1Password originally use the macOS Keychain?

The macOS Keychain had many benefits that made it a natural choice:

  • It is shipped on every Mac and used by millions of people, making it robust and well tested.
  • It is open source, helping to ensure its encryption algorithms are well designed and free of errors.
  • By using the macOS Keychain, 1Password didn’t need a single line of encryption code.
  • The macOS Keychain is supported by Apple, helping to ensure it will be around for many years to come.
  • Additional security measures like automatic locking are built in.
  • Locking is handled by a central process, meaning unlocking the keychain in one application will automatically unlock it for all other applications.
  • MobileMe syncing was built into the macOS Keychain.

How can the Agile Keychain be even better?

As 1Password matured and became more mainstream, many people started requesting features that were not possible with the macOS Keychain. Although the benefits of the macOS Keychain were many, they were outweighed by the following drawbacks:

  • Syncing data without using MobileMe was not realistic because of the single-file format used by the macOS Keychain.
  • Syncing with the iPhone or iPod touch was not supported.
  • The macOS Keychain is Apple exclusive, making cross-platform support difficult. We looked at migrating the macOS Keychain code to other environments, but it was not a simple task and the reward was questionable.
  • Many people, especially those new to the platform, have never heard of the macOS Keychain. They were often confused by the prompts the macOS Keychain presents. Even worse, having never used the Keychain Access application, they had difficulty performing common tasks like changing their password, automatic lock settings, and sync options.
  • The macOS Keychain used Triple DES as its encryption algorithm at the time which was quite secure but was superseded by newer encryption algorithms with longer key lengths. The US government deprecated the use of Triple DES and set AES as its new standard.
  • The macOS Keychain’s automatic lock function is based on usage of the keychain itself, not your activity, such as typing and mouse usage. Many people wanted the automatic lock feature to be based on their use of the computer, not the length of time between keychain uses.
  • As the macOS Keychain size grows, its performance deteriorates significantly. The main cause of this is how updates are handled. When updating any data, a separate temporary file is created with a full copy of the original keychain, and then copied over. As the file size increases, copying the original file contents becomes very slow.
  • MobileMe syncing of keychains was often unreliable, causing item duplication, deletion, and creation of corrupt entries that could not be accessed. Because 1Password was simply accessing the macOS Keychain, it was impossible to fix these issues ourselves.

Decision to develop the Agile Keychain

The macOS Keychain served 1Password very well. With the introduction of the iPhone SDK and the many great ideas for improvement from our customers, the drawbacks associated with the macOS Keychain started to outweigh the benefits. In fact, while investigating alternatives we realized that the main benefits of the macOS Keychain could all be achieved in other ways while learning from its existing limitations and avoiding them.

In the end, the greatest motivation to make a change was syncing. When Leopard and MobileMe were released, the reliability of the macOS Keychain syncing became spotty at best. Given that syncing is one of the most important things for a password manager, it is unacceptable to have any unreliability in this area.

The Agile Keychain format was created to address these issues while building on the tenets of the macOS Keychain. It was introduced in 2008, replacing our use of the macOS Keychain at that time.

The goal of the Agile Keychain was to build on the successes of the macOS Keychain while increasing flexibility and portability. Additional flexibility was needed to enable new features and stronger security beyond the scope of the macOS Keychain, as well as to make it easier to integrate with other platforms.

Requirements

Our customers demand a lot from 1Password, so we set some high goals when designing the Agile Keychain format:

  • It must not require a single line of encryption code to be written. Encryption code is tricky and is best left to experts.
  • All encryption and key generation code must be well reviewed by the professional community. Having a large userbase is critical to ensure the code is robust, well tested, and well supported by the community.
  • Automatic locking, including on sleep, screen saver activation, and a configurable period of inactivity.
  • It must be accessible on many platforms, such as iOS and Windows.
  • Fast performance that does not degrade as the keychain size increases.
  • It must be accessible by multiple applications but not require every application to unlock the keychain individually.
  • The design should minimize the root causes of common sync problems such as conflicts, duplicate items being created, items deleted for no apparent reason, and the creation of corrupt entries that cannot be accessed.

Design Decisions

The following design decisions were made with the goal of fulfilling the above requirements.

Encryption algorithms and protocols should be Open Source wherever possible.

As always, we did not want to write a single line of encryption code. We work hard to understand the details and the principles of cryptology behind the systems that we use, but we know enough to understand that we should rely on the professional community for all encryption code.

When creating, reading, or manipulating the Agile Keychain, 1Password uses a combination of the OpenSSL library, CommonCrypto, or Windows cryptography libraries depending on platform and version for all of its encryption and key generation needs.

The core of the encryption is AES (Advanced Encryption Standard) using 128-bit encryption keys and performed in Cipher Block Chaining (CBC) mode along with a randomized Initialization Vector.

128 bit keys versus 256-bit keys

AES supports the use of 128-, 192-, and 256-bit keys. We opted for 128-bit keys at the time the Agile Keychain was created because the performance and portability advantages outweighed the negligible security gain of using 256-bit keys. 128-bit keys are extremely secure.

We use 256-bit keys in the OPVault format but not for reasons one might expect. There is a technical sense in which AES 256 is enormously stronger than AES 128, but in every sense that actually matters for security there is no difference. At 128 bits, this is already the strongest part of the system. No attacker would attempt a brute force attack against a 128-bit key.

Encryption Key Generation

The most important component of encryption, which is often overlooked, is how the encryption keys are generated. This needs to be done in a way that ensures the mathematics of the AES algorithm cannot be avoided while also stymying brute force attacks.

The first thing to look at is the randomness of the keys themselves. In all versions of 1Password, we use cryptographically appropriate random number generation processes to create the keys. The details differ across platforms and versions, but in each case we follow best practices in creating the 128-bit keys.

The second thing to look at is how your Master Password is processed to decrypt your key. The Agile Keychain uses PBKDF2 to generate encryption keys from your password. PBKDF2 is also published by the Internet Engineering Task Force in RFC 2898. You can find out more about PBKDF2 in our blog post on the topic.

Hierarchy of Encryption Keys

To allow you to change your password without needing to decrypt and re-encrypt the entire Agile Keychain, an encryption key hierarchy was created. Instead of encrypting data with the password directly, a random key of 1024 bytes is used. This password is generated by cryptographically appropriate random number generators, relying in part on true random numbers where the operating system supports that. This key is stored in the encryptionKeys.js file, encrypted using PBKDF2 from the Master Password.

By using such a huge random key, your password can be changed by simply decrypting and re-encrypting the keys stored in encryptionKeys.js.

When the Agile Keychain format was first designed, we wanted to leave open the possibility of enabling multiple security levels. Thus, you will see that some keys are labeled with SL5 and some SL3. SL5 is the only level that is relevant in today’s usage.

File System Storage

Every item in the Agile Keychain is stored as a separate file. By using individual files, syncing of the Agile Keychain can be performed using off-the-shelf sync solutions. This allows for greater flexibility because people can choose their own sync solution.

Individual Entry Contents

The above file format is based on JSON. It is a lightweight notation for structuring data without the overhead associated with formats like XML. The name of the file is based on the UUID (Universally Unique Identifier) of the item. This guarantees the filename is unique and will stay the same even when items are renamed.

Here is an example entry from the Agile Keychain:

{
    "title" : "Example Login",
    "locationKey" : "example.com",
    "encrypted" : "...",
    "typeName" : "webforms.WebForm",
    "securityLevel" : "SL5",
    "openContents" : {
        "createdAt" : 1216012929,
        "updatedAt" : 1216012929,
        "usernameHash" : "...",
    },
    "location" : "https://example.com/account/login",
    "uuid" : "0A522DFCAE6442D991145BC76E55D343",
    "folderUuid" : "A90D66D1A4E34481BDF03DDEA9F511AC"
}

As you can see, not all the information is encrypted. For example, the title of each entry (“Example Login”) and the location (https://example.com/account/login) are open. Having these open allows 1Password to organize your data and display it without suffering the performance hit of needing to decrypt every single item. All the sensitive information is stored in the encrypted section of the file.

Unlocked vaults or unlocked boxes

To better understand what information is and isn’t encrypted in the Agile Keychain some background is required. This will involve a change of metaphor for how to think about what it means when your data are locked or unlocked.

For your security, the Agile Keychain decrypts as little information as possible at any given moment. 1Password presents this as either “locked” or “unlocked”. The impression someone might get from this is that when 1Password is unlocked, all of the information in an Agile Keychain is suddenly decrypted. This, however, is not how 1Password really works. Imagine, instead of a vault that is locked or unlocked, a room full of locked boxes. Each box requires a key to open it, the same key. When you have entered your Master Password, that key is available although all of the boxes still remain locked. At various times 1Password will select a box and unlock that particular one. When it is done with the contents of that box, it will lock it again.

When you go to a login page, 1Password needs to find all of the boxes that could potentially be a Login for that location. It also needs to present you with a list of those potential Logins so that you can choose among them. Conceivably (but incorrectly), 1Password could go and unlock each box in the room looking through their contents to determine which ones are potential matches. But that would take a very long time. Opening a single box doesn’t take any noticeable time, but opening all of them would be prohibitively slow.

What we did in the Agile Keychain is put labels on the outside of each box. The labels contain, most importantly, the web location associated with that Login and the title that you gave to that Login. This way 1Password can scan the locations quickly without having to unlock any boxes. It can then present you with the titles of the ones that are potential matches. After you select a particular Login to fill, 1Password will unlock the particular box.

The downside of this is that the Agile Keychain had to keep the titles and the web locations unencrypted. In the OPVault format, we found a way to work with all data encrypted.

Do security improvements in OPVault mean that Agile Keychain is unsafe?

Agile Keychain remains safe in the same way that an iPhone 5 remains a great device even after Apple released a newer model. We have always worked to design systems that defend against future threats, and so the security enhancements in OPVault are looking toward the future.

It’s not that Agile Keychain is no longer secure, it’s just that OPVault is secure-er.

Published: