How Google Chrome Stores Passwords

Every browser released in the last decade has some sort of password
management system, and Google Chrome is no different. I've been sifting
through the Chrome source code, released under the open source project
Chromium, and I've found out how
they do it. In this tutorial, I'll post all of the source code used by
Google Chrome to quickly and securely save your passwords.

Let's start at the top and work our way down. Any time a password is
saved, you're first prompted with the save password bar.

In Chrome, this object is called PasswordManager. This object is
responsible for a lot of stuff, but what we really care about is what
happens when you click "Save Password".

form_manager is another object, PasswordFormManager, that sits between
the user interface and the database. All this function does is call that
object's Save method. It then instructs the save password prompt to
close. Here's what the Save function looks like.

Again, pretty straight forward. The first two items will log information
for debugging purposes and aren't compiled in release mode. It then
checks if it is adding a new password or updating an existing one. For
the purposes of this tutorial, let's look at adding a new password.

void PasswordFormManager::SaveAsNewLogin() {
DCHECK_EQ(state_, POST_MATCHING_PHASE);
DCHECK(IsNewLogin());
// The new_form is being used to sign in, so it is preferred.
DCHECK(pending_credentials_.preferred);
// new_form contains the same basic data as observed_form_ (because its the
// same form), but with the newly added credentials.
DCHECK(!profile_->IsOffTheRecord());
WebDataService* web_data_service =
profile_->GetWebDataService(Profile::IMPLICIT_ACCESS);
if (!web_data_service) {
NOTREACHED();
return;
}
pending_credentials_.date_created = Time::Now();
web_data_service->AddLogin(pending_credentials_);
}

Most of this function is debug code. What we care about is the call to
AddLogin. The WebDataService object is responsible for meta data
associated with a web page.

Now we're getting a little more complicated. Adding a password is done
asynchronously and this function handles scheduling that task. It seemed
to be very important that nothing interrupt Chrome's user interface -
this keeps it feeling fast and responsive. Now let's take a look at what
happens when this task is run.

We've finally reached the end of the line. This function actually builds
the SQL statement for adding a new password to Chrome's SQLite database.
Of course, the password isn't stored in plain text so Chrome has an
Encryptor object responsible for encrypting the password first. Let's
take a look at that.

The important piece here is CryptProtectData, which is a Windows API
function for encrypting data. Data encrypted with this function is
pretty solid. It can only be decrypted on the same machine and by the
same user that encrypted it in the first place.

So what'd we learn by investigating Chrome's password management system?
Well, we learned that Google uses SQLite as the storage mechanism for
passwords and other web page related data. We also see that Google has
done a great job extracting Windows specific code from the
cross-platform stuff. The only Windows specific code here is the
encryption function, which can easily be ported by creating a different
Encryptor object for each OS.

That does it for this walk-through of Google Chrome's password storage
mechanism. It's always neat to see how other projects get things done.
And of course, a chance to see Google's code in action is never
something to pass up.