Decrypt Chrome Linux BLOB encrypted cookies in Python

I have Chrome 33+ in Ubuntu and I see that the cookies are encrypted in a BLOB structure:

CREATE TABLE cookies (creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,host_key TEXT NOT NULL,name TEXT NOT NULL,value TEXT NOT NULL,path TEXT NOT NULL,expires_utc INTEGER NOT NULL,secure INTEGER NOT NULL,httponly INTEGER NOT NULL,last_access_utc INTEGER NOT NULL, has_expires INTEGER NOT NULL DEFAULT 1, persistent INTEGER NOT NULL DEFAULT 1,priority INTEGER NOT NULL DEFAULT 1,encrypted_value BLOB DEFAULT '');

I would like to write a python script to decrypt the cookie. I've seen that there is Cookie issue with Chrome 33 Beta but relies in CryptUnprotectData that it's a Windows API.

First of all I would like to know how are the cookies encrypted. I've read 3DES and AES but I don't find a trusty source to get the info.

I will write the code to do the necessary encryption and decryption if I have info about how to do it.

Thank you


I've posted an example Python script here for decoding the encrypted cookies in either OSX or Linux.


I have been working on it too. Until now I have found that Chrome(Windows) uses CryptProtectData function to encrypt it's cookie's values. The same function it has been using to encrypt saved passwords in Login Data file. CryptProtectData uses the user account information and password of the logged in windows user to encrypt data. To decrypt it we have to use CryptUnProtectData function with the same user account logged in.

Here is a snippet to decrypt Login Data https://gist.github.com/jordan-wright/5770442

Now regarding Linux I have read here: http://www.linkedin.com/groups/Google-Chrome-encrypt-Stored-Cookies-36874.S.5826955428000456708

on other systems it seems to obfuscate passwords with the salt "saltysalt" and the password "peanuts"


The comments are a bit confusing so just to clarify, this is the chromium source in os_crypt_win.cc so you can see it's just putting the string into a blob and running CryptUnprotectData()

bool OSCrypt::DecryptString(const std::string& ciphertext,
                            std::string* plaintext) {
  DATA_BLOB input;
  input.pbData = const_cast<BYTE*>(
      reinterpret_cast<const BYTE*>(ciphertext.data()));
  input.cbData = static_cast<DWORD>(ciphertext.length());

  DATA_BLOB output;
  BOOL result = CryptUnprotectData(&input, NULL, NULL, NULL, NULL,
                                   0, &output);
  if (!result)
    return false;

  plaintext->assign(reinterpret_cast<char*>(output.pbData), output.cbData);
  LocalFree(output.pbData);
  return true;
}