New issue
Advanced search Search tips
Starred by 8 users

Issue metadata

Status: Unconfirmed
Owner: ----
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: ----
Type: Bug

Sign in to add a comment

Security: Chrome Sync passphrase is far too easy to bruteforce

Reported by, Mar 12 Back to list

Issue description

Documentation states the following:

> With a passphrase, you can use Google's cloud to store and sync your Chrome data without letting Google read it.

That's not currently true. The encryption key for the data is derived from the passphrase using PBKDF2-HMAC-SHA1 using a fixed salt and merely 1003 iterations. This doesn't provide significant protection against bruteforcing the passphrase. Worse yet, if somebody manages to access encrypted data from multiple user accounts, the fixed salt allows bruteforcing all of them at the same time.

The sequence in code is the following:

* SyncEncryptionHandlerImpl::SetCustomPassphrase(passphrase),
* Cryptographer::AddKey({"localhost", "dummy", passphrase}),
* Nigori::InitByDerivation("localhost", "dummy", passphrase),

InitByDerivation() will derive a salt first. Given that the input is fixed however, that salt is a constant: Suser = PBKDF2("localhostdummy", "saltsalt", 1001, 8). It will then derive the encryption key as Kenc = PBKDF2(passphrase, Suser, 1003, 16). So in order to find any Google Sync accounts using "password1" as passphrase, an attacker would only need to derive an encryption key from that passphrase once and try to decrypt the data for any accounts it can access.

Even with a salt that isn't fixed but rather based on account ID for example, 1003 iterations are a way too low hurdle today. Judging by the numbers provided in, a single Nvidia GTX 1080 GPU would be able to calculate 3.2 million PBKDF2-HMAC-SHA1 hashes with 1003 iterations per second. That's enough to go through the enormous list of passwords under in less than 8 minutes. Even the passphrase of users who didn't reuse passwords and chose a passphrase with 40 bits of entropy (that's already stronger than most of them) would be guessed within two days.

I'd consider 256,000 PBKDF2-HMAC-SHA1 iterations or 100,000 PBKDF2-HMAC-SHA256 iterations the bare minimum that is still acceptable today. And each user should have their individual salt of course.

Comment 1 by, Mar 12 (6 days ago)

Components: Security Services>Sync Privacy
Labels: -Type-Bug-Security -Restrict-View-SecurityTeam Type-Bug

Comment 2 by, Mar 15 (4 days ago)

On an external post is also this note that probably bears fixing at the same time, but isn't a security issue:

"The function in question manages to run PBKDF2 four times where one run would have been sufficient. First run derives the salt from host name and username (both happen to be constants in case of Chrome Sync). This is pretty pointless: a salt doesn’t have to be a secret, it merely needs to be unique. So concatenating the values or running SHA-256 on them would do just as well. The next three runs derive three different keys from identical input, using different iteration counts. A single PBKDF2 call producing the data for all three keys clearly would have been a better idea."

Sign in to add a comment