Agile Keychain Design

The Agile Keychain format was introduced in 2008, replacing our use of the OS X Keychain. These are the files/folders typically called 1Password.agilekeychain

The goal of the Agile Keychain file is to build on the successes of the Mac OS X keychain while increasing the flexibility and portability of the keychain design. Additional flexibility is needed to enable new features and stronger security beyond the scope of the Mac OS X keychain, as well as to make it easier to integrate with other platforms like iOS, Android, Windows, and Linux.

The specific needs for which the Agile Keychain file format was created are documented in the History of 1Password’s OS X Keychain Integration. This document will cover the requirements of the Agile Keychain and detail how its design meets them.

Requirements

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

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. These libraries are compliant with the FIPS 140-1 and FIPS 140-2 Federal Information Processing Standards.

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 because the performance and portability advantages outweighs the negligible security gain of using 256 bit keys. 128-bit keys are extremely secure and short enough to allow devices like the iPhone and web browsers to quickly decrypt their contents. The extra computation required for 256-bit encryption was simply not justifiable given the astronomical nature of a 128-bit key. According to the National Institute of Standards and Technology:

What is the chance that someone could use the “DES Cracker”-like hardware to crack an AES key?

In the late 1990s, specialized “DES Cracker” machines were built that could recover a DES key after a few hours. In other words, by trying possible key values, the hardware could determine which key was used to encrypt a message.

Assuming that one could build a machine that could recover a DES key in a second (i.e., try 255 keys per second), it would take that machine approximately 149 thousand billion (149 trillion) years to crack a 128-bit AES key. To put that into perspective, the universe is believed to be fewer than 15 billion years old.

We felt that adding an extra 128 bits, i.e., multiplying 149 trillion years by an extra 3.4 x 1038, was not worth the performance cost that would be incurred. 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.

Additionally, the operating system on the iPhone, iPod touch, and iPad provides a standard, hardware-accelerated implementation of AES-128. With security algorithms and protocols, it is always better to rely on well-tested and reviewed implementations than to develop one’s own.

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 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 the standard PBKDF2 (Password-Based Key Derivation Function) algorithm 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.

Of course, we wanted to avoid writing this code in the Agile Keychain and elected to use open and trusted implementations. We use PBKDF2 with HMAC_SHA1 (That’s a Hash-based Message Authentication Code using the Secure Hash Algorithm version 1.) When we first introduced the Agile Keychain, we used 1000 iterations, but the format was modified in 2010 to allow more flexibility and increased numbers of iterations. The exact number of PBKDF2 iterations will depend on platform, version, and the capabilities of the machine that a new Agile Keychain is created on. This provides us flexibility in anticipating future threats.

Why is it so important to strengthen the encryption key? There are tools available that specialize in cracking password hashcodes. The Lighting Hash Cracker, for example, is able to test millions of passwords per second. If a naive key generation algorithm that simply hashed the password once were used to generate the key, attackers could use a system like this to quickly brute force the password. By using, say, 10000 iterations in the PBKDF2 function, the brute force attack is effectively 10000 times more difficult.

Hierarchy of Encryption Keys

In order 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 users 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. Additionally, you can use different passwords on different devices. For example, the master password you use on your computer might be difficult to type on an iPhone, so it is useful to be able to create a different one on the iPhone.

The other advantage of this setup is that it allows multiple security levels to be defined. Each time a new security level is created, we simply generate another key to encrypt items that use that level of security. One example of this is on the iPhone, where a simple PIN can be used to protect less important items, while the master password is required for more sensitive items.

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 any of the many file syncing solutions available on Mac OS X. In fact, many sync solutions like Dropbox can sync files between Mac, Windows, and Linux.

Individual Entry Contents

The Agile Keychain is nearly identical to the Mac OS X keychain in terms of what is kept encrypted and what is left open in plain text. The distinction is an important trade-off between security and convenience. The more that is encrypted, the less a would-be thief can access, but it is also necessary to leave enough open to allow applications to freely access certain items without needing to decrypt every single entry each time. The Mac OS X keychain nicely balances security and convenience, so the Agile Keychain follows suit.

Here is an example entry from the Agile Keychain:


{
 "title" : "dave @ AWS login",
 "locationKey" : "perfora.net",
 "encrypted" : "...",
 "typeName" : "webforms.WebForm",
 "securityLevel" : "SL5",
 "openContents" : {
   "createdAt" : 1216012929,
   "updatedAt" : 1216012929,
   "usernameHash" : "...",
 },
 "location" : "https://webmailcluster.perfora.net:443/xml/webmail/Login",
 "uuid" : "0A522DFCAE6442D991145BC76E55D343",
 "folderUuid" : "A90D66D1A4E34481BDF03DDEA9F511AC"
}

As you can see, not all the information is encrypted. Most notably, the name/title of each entry (i.e. dave @ AWS login) and the location/URL 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 truly confidential information is stored in the encrypted section of the file.

The original form of the Agile Keychain left its assessment of password strength among the unencrypted data. This was removed in 2011.

The above file format is based on JSON (JavaScript Object Notation). It is a lightweight notation for structuring data without the overhead associated with formats like XML. As a side benefit, these JSON files can be loaded directly into a web browser. 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.

Summary

The design decisions made when developing the Agile Keychain provide the following benefits: