I’m taking a detailed look at how 1Password works, originally to help examine potential risks when used in a corporate environment, and eventually because I’m just a nerd and love All Things Crypto. (See this page for an introduction and background).

Last time, I explained how the 1Password Two-Secret Key Derivation Process (2SKD) works. Briefly, it takes your email address, master password, and secret key, along with a couple other parameters, and derives a strong Master Unlock Key or MUK.

That MUK then decrypts the “master key” or “mk” for the primary account on the client, which then begins the process for decrypting that account’s data vaults. The mk is also used to unlock the mk for any additional accounts on that client, by unlocking specific entries in the “accounts” table.

That’s how it works on a Mac. Under Windows, things are a little different. I’ll talk about 1Password version 6 on Windows (I haven’t had a chance to upgrade my Windows VM to version 7).

Unlocking the Client

To unlock the Windows client, you need only one thing: the Master Password. This is (potentially) because it’s more difficult to safely store the account key on a Windows machine, or perhaps because this is the way it’s always been done and they simply haven’t updated the client to be more like the macOS approach. I’m really not sure.

Like on the Mac, the user’s master password is iterated through thousands of rounds of PBKDF2. But the number of rounds is not fixed, and actually is re-computed with every unlock. If it takes less than a second to derive the key, then the EMK is updated using a higher iteration count.

The result of this PBKDF2 step is not the actual key, however. It’s a little more complicated that that.

The Encrypted Master Key

In the “config” table is an entry for EncryptedMasterKey (EMK). This is a binary structure that includes two parts:

The header includes the iteration count and salt for the initial key-derivation step. The opdata vault contains the actual Master Key, which is then used to begin the decryption process. The Master Key is encrypted, using the key derived from the password. Hence, Encrypted Master Key.

EMK Structure

The header is composed of an 32-bit unsigned integer giving the number of iterations, another 32-bit integer providing the length of the salt, the salt itself, and then a 32-bit integer with the length of the following payload.

The payload is a standard encrypted format used by Agilebits throughout the 1Password system. It includes its own header: the string “opdata01” and a 64-bit integer giving the plaintext length. This is followed by the 16-byte initialization vector (IV), the actual AES-CBC encrypted ciphertext, and finally a 32-byte HMAC signature.

Encrypted Master Key Structure

Encrypted Master Key Structure

Because AES requires a fixed block size of 128 bits (16 bytes), the plaintext must be padded to bring its total length to an even multiple of 16. If it’s already at an even multiple, then a full new block of 16 bytes is randomly generated. Unlike most padding systems, however, this random padding is put at the front of the plaintext, rather than being added at the end. This helps to reduce the potential for padding-oracle and similar attacks.

To decrypt the opdata vault, we need the AES encryption key, and also the HMAC key. The HMAC key is used to generate a secure message digest, and is applied to the entire opdata structure (not including the HMAC tag itself). So the header (opdata01), plaintext length, IV, and Ciphertext, are all fed into the HMAC function using the HMAC key, and the result of this is appended to the end of the ciphertext.

When decrypting the vault, the HMAC key is used to re-generate the signature. If the signature doesn’t match the signature read from the end of the opdata vault, then it’s assumed that the ciphertext has been altered (deliberately or by accident) and the decryption fails before it even begins. If the signatures match, then it’s an indication that the ciphertext hasn’t been changed, and the decryption can proceed.

So we need two keys: a 256-bit AES key, and a similar 256-bit HMAC key, for a total of 512 bits.

Deriving the Encryption and HMAC Keys

Fortunately, we have a SHA function that produces exactly 512 bits. Remember, we feed the user’s password, the salt from the EMK header, and the iteration count (also from the header) into the PBKDF2 function. By using SHA-512 as the hashing function for PBKDF2, it generates 512 bits (or 64 bytes) of password-derived data. The first 32 bytes of the output are used as the AES key, and the second 32 bytes for the HMAC key. Here’s how it looks:

(you’ll see huge dumps like this frequently through this series. I’m trying to show raw data, highlight individual important bits, provide results of intermediate computations, and so forth. Again, the goal is to give you enough information that you can easily debug your own code, if you decide to play with the tech yourself. If you just want to see the results, look at the end of this big block.)

$ python do_emk.py 
Enter EMK data (from config table) in base64 or hex: rPwIABAAAADBxTVJptTc4ShV-auZirBMkAAAAG9wZGF0YTAxQAAAAAAAAADpLFfPKxiEVt6v3fRJ-W6whU7c_zaO9b9q9UPgUQ7Q12LvjHq8-mImCneHxos4qw_jIC89Iz1BmMhWhcSdbvGlYx1XBdXhSDM2jz4h8_zCqDpjnDqUknDfHruv0gVTjPdY7fMXiPyETpHrM2NUZ2omyfFKSOeYsXdSN_c276HMVg==

Enter the master password:
Password: [update-clown-squid-bedpost]
*** EMK Structure from DB

RAW HEX              acfc 0800 1000 0000 c1c5 3549 a6d4 dce1 
                     2855 f9ab 998a b04c 9000 0000 6f70 6461 
                     7461 3031 4000 0000 0000 0000 e92c 57cf 
                     2b18 8456 deaf ddf4 49f9 6eb0 854e dcff 
                     368e f5bf 6af5 43e0 510e d0d7 62ef 8c7a 
                     bcfa 6226 0a77 87c6 8b38 ab0f e320 2f3d 
                     233d 4198 c856 85c4 9d6e f1a5 631d 5705 
                     d5e1 4833 368f 3e21 f3fc c2a8 3a63 9c3a 
                     9492 70df 1ebb afd2 0553 8cf7 58ed f317 
                     88fc 844e 91eb 3363 5467 6a26 c9f1 4a48 
                     e798 b177 5237 f736 efa1 cc56           

Iterations           acfc 0800                               

Salt len             1000 0000                               

Salt                 c1c5 3549 a6d4 dce1 2855 f9ab 998a b04c 
*** Encryption Key and HMAC Key, derived from password:

Raw derived key      5f5b a609 9b25 9989 8a32 9b52 638d 7149 
                     3a9c 12c9 5353 9f34 3072 0afc b3f0 7014 
                     71ed 9b82 1d30 515e e71d 5640 6747 84da 
                     c9b3 63f2 8730 7983 541c a4a9 ddff 144f 

Derived enc key      5f5b a609 9b25 9989 8a32 9b52 638d 7149 
                     3a9c 12c9 5353 9f34 3072 0afc b3f0 7014 

Derived hmac key     71ed 9b82 1d30 515e e71d 5640 6747 84da 
                     c9b3 63f2 8730 7983 541c a4a9 ddff 144f 

** Decrypting OPDATA structure

raw opdata           6f70 6461 7461 3031 4000 0000 0000 0000 
                     e92c 57cf 2b18 8456 deaf ddf4 49f9 6eb0 
                     854e dcff 368e f5bf 6af5 43e0 510e d0d7 
                     62ef 8c7a bcfa 6226 0a77 87c6 8b38 ab0f 
                     e320 2f3d 233d 4198 c856 85c4 9d6e f1a5 
                     631d 5705 d5e1 4833 368f 3e21 f3fc c2a8 
                     3a63 9c3a 9492 70df 1ebb afd2 0553 8cf7 
                     58ed f317 88fc 844e 91eb 3363 5467 6a26 
                     c9f1 4a48 e798 b177 5237 f736 efa1 cc56 

Header               6f70 6461 7461 3031                     

PT length            4000 0000 0000 0000                     

IV                   e92c 57cf 2b18 8456 deaf ddf4 49f9 6eb0 

CT                   854e dcff 368e f5bf 6af5 43e0 510e d0d7 
                     62ef 8c7a bcfa 6226 0a77 87c6 8b38 ab0f 
                     e320 2f3d 233d 4198 c856 85c4 9d6e f1a5 
                     631d 5705 d5e1 4833 368f 3e21 f3fc c2a8 
                     3a63 9c3a 9492 70df 1ebb afd2 0553 8cf7 
CT length (padded): 80

HMAC digest          58ed f317 88fc 844e 91eb 3363 5467 6a26 
                     c9f1 4a48 e798 b177 5237 f736 efa1 cc56 

Verifying HMAC tag

OPdata Msg           6f70 6461 7461 3031 4000 0000 0000 0000 
                     e92c 57cf 2b18 8456 deaf ddf4 49f9 6eb0 
                     854e dcff 368e f5bf 6af5 43e0 510e d0d7 
                     62ef 8c7a bcfa 6226 0a77 87c6 8b38 ab0f 
                     e320 2f3d 233d 4198 c856 85c4 9d6e f1a5 
                     631d 5705 d5e1 4833 368f 3e21 f3fc c2a8 
                     3a63 9c3a 9492 70df 1ebb afd2 0553 8cf7 

HMAC key             71ed 9b82 1d30 515e e71d 5640 6747 84da 
                     c9b3 63f2 8730 7983 541c a4a9 ddff 144f 

Computed HMAC        58ed f317 88fc 844e 91eb 3363 5467 6a26 
                     c9f1 4a48 e798 b177 5237 f736 efa1 cc56 
HMAC signature verified.



*** decrypted opdata

Plaintext            7205 250f bddb 7663 1829 4b69 bf70 b01e 
                     09db 23cf df4c 1ba6 be18 b910 aa11 75b5 
                     ad14 d4fe 0938 f49f f283 28c9 3f9c 821a 
                     6544 0753 b788 cc63 68b1 3b57 ae85 426b 



Master Enc Key       7205 250f bddb 7663 1829 4b69 bf70 b01e 
                     09db 23cf df4c 1ba6 be18 b910 aa11 75b5 
(base-64)            cgUlD73bdmMYKUtpv3CwHgnbI8_fTBumvhi5EKoRdbU=

Master HMAC Key      ad14 d4fe 0938 f49f f283 28c9 3f9c 821a 
                     6544 0753 b788 cc63 68b1 3b57 ae85 426b 
(base-64)            rRTU_gk49J_ygyjJP5yCGmVEB1O3iMxjaLE7V66FQms=

Enc+HMAC together    cgUlD73bdmMYKUtpv3CwHgnbI8_fTBumvhi5EKoRdbWtFNT-CTj0n_KDKMk_nIIaZUQHU7eIzGNosTtXroVCaw==

Login Details

On macOS clients, we would use the MUK to decrypt the master key in the keysets entry for the primary account. But we don’t have the MUK, we have something else. But the vault is the same as on the Mac (it’s just stored as-is on the cloud, after all) – so we need to build the MUK. How do we do that without the user’s Secret Key?

Just as on macOS, the accounts table includes an “enc_login” field. On Windows, however, this is another opdata vault, encrypted using the keys we just derived.

EMK, login details, and MUK

EMK, login details, and MUK

$ python opdata.py 
Enter 64-byte key (AES + HMAC) (hex or base64): cgUlD73bdmMYKUtpv3CwHgnbI8_fTBumvhi5EKoRdbWtFNT-CTj0n_KDKMk_nIIaZUQHU7eIzGNosTtXroVCaw==

Enter OPDATA binary (hex or base64): b3BkYXRhMDFkAAAAAAAAAOdAtGkH6N-oMZTnKBe-TadkOx6mviKTvkxolQSENTKUp6TCueQtKTBPdGg9eLBoNRph22ZYegLinJ6k5bUAD3_A9QrlaQ_W6uZv1nz1hfH3gZVTK9d4UzaRTNDtIF7-dy8QIOajiNe5hwYyGAPYA1B7YaLfeEMCi6fP2xoEvWwQ7IMV_mrxzZFsJYD1rmKS_2zZhBHQ1ywHApOmCvO4OXY=

** Decrypting OPDATA structure

raw opdata           6f70 6461 7461 3031 6400 0000 0000 0000  
                     e740 b469 07e8 dfa8 3194 e728 17be 4da7  
                     643b 1ea6 be22 93be 4c68 9504 8435 3294  
                     a7a4 c2b9 e42d 2930 4f74 683d 78b0 6835  
                     1a61 db66 587a 02e2 9c9e a4e5 b500 0f7f  
                     c0f5 0ae5 690f d6ea e66f d67c f585 f1f7  
                     8195 532b d778 5336 914c d0ed 205e fe77  
                     2f10 20e6 a388 d7b9 8706 3218 03d8 0350  
                     7b61 a2df 7843 028b a7cf db1a 04bd 6c10  
                     ec83 15fe 6af1 cd91 6c25 80f5 ae62 92ff  
                     6cd9 8411 d0d7 2c07 0293 a60a f3b8 3976  

Header               6f70 6461 7461 3031                      
PT length            6400 0000 0000 0000                      
IV                   e740 b469 07e8 dfa8 3194 e728 17be 4da7  
CT                   643b 1ea6 be22 93be 4c68 9504 8435 3294  
                     a7a4 c2b9 e42d 2930 4f74 683d 78b0 6835  
                     1a61 db66 587a 02e2 9c9e a4e5 b500 0f7f  
                     c0f5 0ae5 690f d6ea e66f d67c f585 f1f7  
                     8195 532b d778 5336 914c d0ed 205e fe77  
                     2f10 20e6 a388 d7b9 8706 3218 03d8 0350  
                     7b61 a2df 7843 028b a7cf db1a 04bd 6c10  
CT length (padded): 112

HMAC digest          ec83 15fe 6af1 cd91 6c25 80f5 ae62 92ff  
                     6cd9 8411 d0d7 2c07 0293 a60a f3b8 3976  

Verifying HMAC tag

OPdata Msg           6f70 6461 7461 3031 6400 0000 0000 0000  
                     e740 b469 07e8 dfa8 3194 e728 17be 4da7  
                     643b 1ea6 be22 93be 4c68 9504 8435 3294  
                     a7a4 c2b9 e42d 2930 4f74 683d 78b0 6835  
                     1a61 db66 587a 02e2 9c9e a4e5 b500 0f7f  
                     c0f5 0ae5 690f d6ea e66f d67c f585 f1f7  
                     8195 532b d778 5336 914c d0ed 205e fe77  
                     2f10 20e6 a388 d7b9 8706 3218 03d8 0350  
                     7b61 a2df 7843 028b a7cf db1a 04bd 6c10  

HMAC key             ad14 d4fe 0938 f49f f283 28c9 3f9c 821a  
                     6544 0753 b788 cc63 68b1 3b57 ae85 426b  

Computed HMAC        ec83 15fe 6af1 cd91 6c25 80f5 ae62 92ff  
                     6cd9 8411 d0d7 2c07 0293 a60a f3b8 3976  
HMAC signature verified.

*** decrypted opdata

Plaintext            7b22 6163 636f 756e 744b 6579 223a 2022  
                     4133 2d41 5357 5759 422d 3739 384a 5259  
                     2d4c 4a56 4434 2d32 3344 4332 2d38 3654  
                     564d 2d48 3433 4542 222c 2022 7061 7373  
                     776f 7264 223a 2022 7570 6461 7465 2d63  
                     6c6f 776e 2d73 7175 6964 2d62 6564 706f  
                     7374 227d                                

{"accountKey": "A3-ASWWYB-798JRY-LJVD4-23DC2-86TVM-H43EB", "password": "update-clown-squid-bedpost"} 

Login details for secondary accounts are also encrypted the same way – using this key we just derived from the user’s password.

Unlocking Multiple Accounts

Let’s update the multiple-account diagram from the last installment, where we just talked about macOS. This now shows both Mac and Windows decryption chains in the same chart (though in practice, no single database would support both).

Unlocking macOS and Windows Clients

Unlocking macOS and Windows Clients

What’s next?

Also in the accounts table is the user’s email, as we learned last time, the keysets entry includes the 2SKD salt, iterations count, and algorithm information. So now we have enough information to generate the MUK.

Once we’ve done that, we decrypt the master key from the keyset, and can begin decrypting the 1Password vaults themselves.

Next Up: Into the Vaults!