Extension - Where is the "Symmetric Key" stored?

As I understand it, it is a persistent client local key - Where is it stored for e.g. chrome based Browsers?

In the browser’s devtools for the extension’s background.html I used:
chrome.storage.local.get(function(result){console.log(result)})

But keys.cryptoSymmetricKey is just an empty object: {}

@michael3 Welcome to the forum!

Try the following:

bitwardenContainerService.cryptoService.getEncKey().then(e => console.log(e))

@grb Weird, for me bitwardenContainerService.cryptoService has no function.getEncKey, it is just undefiend - Is the function called differently?

Not sure. That information is from a 5-month old Reddit post by @Quexten. Perhaps the codebase has changed since then.

Regardless, I am mostly wondering where / how the “Symmetric Key” is stored. If that function would work / still exist, I could try to look at its source code - But maybe someone already knows the answer? :slight_smile:

What are you trying to accomplish?

I am trying to understand how the encryption works in the Browser Extension and if a copy of the local storage of the extension + master password are (theoretically) enough to decrypt the vault later. For that I need to know where the “Symmetric Key” is stored, as (in my understanding) it plays a crucial part in the encryption/decryption mechanism - Unless there was a recent refactor?

Encryption works the same in all client apps. It is explained in the security white paper. The local vault cache contains the protected symmetric key, which can be decrypted using the master password.

The cache file is a numbered .log file in the following folder (for Chrome on Windows — see documentation for other operating systems or browsers):

%LocalAppData%\Google\Chrome\User Data\Default\Local Extension Settings\nngceckbapebfimnlniiiahkandclblb

If you back up your cache, you should be able to decrypt it later, simply by restoring the file to its original location and then launching (and unlocking) the browser extension. You should disconnect from the internet before you do this, because if you have a stale session cookie, your browser extension will log itself out, clearing the cache.

If I recall, you may need to clear the other files from the extensions local storage before restoring the .log file. I’m not sure if it is necessary to back up (and restore) the entire folder as opposed to just the .log file, but it can’t hurt.

bitwardenContainerService.cryptoService.getUserKey().then(key => console.log(key))
for the user key.

It is present while the extension is unlocked.

Depending on what you want to do, you might need more keys, because the user symmetric key is not the only key used. There is a key hieararchy present. Although currently, in most cases, you can decrypt most entries with this single key.

1 Like

Internally, the master password is used to derive the master key (via pbkdf2/argon2+ hkdf stretching), this is then used to decrypt your encrypted user key, which is used for your own entries. These encrypted keys are all included in the local encrypted copy of your vault, but if you want to achieve something like a backup, please use the export feature instead, because recovering like this might require some level of forensic or at least software engineering experience.

Is this something beyond the use of the user’s symmetric key to get organization keys? If so, care to provide a brief synopsis of what changed in July?

Currently, it is mostly just the org keys (one symmetric key per org, no matter how the collections are divided), which is decrypted with your asymmetric key, which in turn is decrypted using your user symmetric key.

I’m wording this so vaguely though because “cipher key” encryption is around the corner, which has one encryption key per cipher (which in turn is encrypted using your user symmetric key). This helps prevent a certain class of attack against the vaults encryption and integrity. Although my assumption is that the main point of this feature is to make implementing “item sharing” easier, because then the client just needs to share the cipher’s encryption key with the account the item is shared to.

As far as I can tell, vaults will be completely migrated to cipherkey encryption at some point.

Interesting, thanks for the summary!

Unrelated, you wrote in your earlier comment

My own practice is to use the Portable Desktop App as a backup solution, by periodically syncing it and then backing up its data folder (including the data.json). My assumption is that I will always be able access such data by restoring a backed up data folder and launch the Portable Desktop App while disconnected from the internet; I also keep an archive of old versions of the Portable Desktop App, in case there are major changes to the internal architecture that make the old cache files incompatible with future versions of the app. This approach is not dissimilar to what OP seems to be wanting to do (storing copies of the browser extension’s local files, for later decryption), so I hope that your warning to OP is not applicable to my backup approach! If I have missed something that could cause problems with future access to this type of backup, please let me know.

I also keep an archive of old versions of the Portable Desktop App, in case there are major changes to the internal architecture that make the old cache files incompatible with future versions of the app.

I never played around with this too much, but as long as you keep the client versions with the caches, this should be fine, but when anything goes wrong, it quickly gets painful (not impossible, but simply painful) to recover.

I still much prefer json exports, though automating these might be a bit more involved than simply backing up your home directory which will include the desktop clients files. But they give you the piece of mind to recover even 10 years in the future, when the old desktop apps might not run because of missing dependencies.