KEYS: A Password Vault That Lives in This Browser
Every password manager worth using encrypts your vault before it leaves your machine. This one never lets it leave: the encrypted blob sits in this browser's own storage, there is no account to make, no server to trust and no sync. One passphrase turns it into a key with PBKDF2 at six hundred thousand rounds, and AES-256-GCM does the rest. The price of that is plain: lose the passphrase or lose the browser profile, and the vault is gone unless you took a backup.
Unlock the vault
One passphrase opens it. It is not stored anywhere, so there is nobody to ask if you lose it.
New entry
Make a password
Every character comes from the browser's cryptographic random source, picked without bias.
What is weak, reused or duplicated
Checked across the whole vault, here, every time it changes.
Bring passwords in from somewhere else
A CSV exported from 1Password, Bitwarden, LastPass, Chrome or Firefox. The file is read in this tab. Nothing is imported until you have seen what it found.
What will be imported
Take a copy out
The encrypted backup is the same envelope this browser stores, so this page can open it again. Keep it wherever you keep backups; it is only as safe as the passphrase.
This writes every password into a file in the clear. Anyone who opens that file, and anything that syncs, backs up or indexes your downloads folder, reads all of them. It is the right thing to do when you are moving to another manager and the wrong thing to do the rest of the time. Delete the file the moment you are finished with it.
Vault settings
Change the master passphrase
The vault is decrypted with the old passphrase and written again under a new random salt.
Delete this vault
It removes the encrypted blob from this browser. There is no copy anywhere else, so unless you have a backup file it is gone.
What this is, and what it is not
What is actually stored. One item in this browser's localStorage, under the key obscura_keys_v1. It is a JSON object with eight fields and no more: format, which names the envelope; kdf and iterations, which say PBKDF2-SHA256 and 600000; cipher, which says AES-256-GCM; salt, sixteen random bytes in base64; iv, twelve fresh random bytes in base64; ciphertext, the encrypted vault in base64; and saved, the time it was last written. The passphrase is not in there, and nothing in there can be turned back into it. Read the item in your own developer console and you will find exactly those fields and nothing else.
How the key is made. PBKDF2-HMAC-SHA256, 600,000 rounds, over a 16-byte salt drawn from the browser's cryptographic random source, giving a 256-bit AES-GCM key. That is the current OWASP figure for PBKDF2-SHA256 and it is why unlocking takes a visible moment. A fresh IV is drawn for every save, which is what GCM requires and what makes reusing a key safe. Changing the passphrase draws a fresh salt as well, so the old and new envelopes share nothing.
What locking does and does not do. After the idle period, and whenever this tab goes to the background, the decrypted vault is dropped: every field is overwritten, the array is emptied, the key object and the passphrase are let go, and the page re-renders as locked. JavaScript cannot promise more than that. A string the engine has already made is the engine's to free, and until it does, a memory dump of the browser could still hold it. Locking raises the cost of a passing glance at your screen. It is not a defence against someone who owns the machine.
The clipboard is emptied, but it is still the clipboard. A copied password is overwritten after twenty seconds and the page counts down while it waits. If the timer runs out while another window is in front, the browser refuses the write and the page pays the debt the moment you come back. In between, anything on the machine that reads the clipboard can read the password, and on some systems a clipboard history tool will have kept a copy the page cannot reach.
The generator counts entropy honestly. For characters it is log2(pool size) times length, where the pool is exactly the sets you ticked, minus the look-alikes if you asked for that. For words it is log2(1296) per word, which is 10.34 bits, from a list of 1,296 words taken at even intervals from the EFF large wordlist and kept to four to seven letters. Five words is 51.7 bits. Capitalising the words adds nothing to that number, because the generator does it to every word rather than choosing, and the page says so rather than inflating the figure.
The strength reading is a guess, and it says which guess it is. The page asks this site for zxcvbn, at /vendor/zxcvbn/4.4.2/zxcvbn.js, and nothing else; there is no CDN in it. When that loads, the reading is zxcvbn's, which knows about common passwords, keyboard walks, dates and names. When it does not, the page says so, names the path it tried, and falls back to an estimate from length and character variety. That fallback is an upper bound: it cannot tell that a twelve-character password is the name of your dog, so it will call it stronger than it is. Everything else on the page works either way.
Import shows you the mapping before it commits. Exports from 1Password, Bitwarden, LastPass, Chrome and Firefox are recognised by their header row; anything else is mapped by column name where the names are recognisable. The parser handles quoted fields containing commas and newlines, which is what a notes column usually contains. Rows it cannot map are listed with the line number and the reason rather than dropped. Nothing enters the vault until you press the button under the preview.
There is no sync, and there will not be. Syncing needs a server, an account and a way to authenticate to both, which is the thing this site does not do. Move a vault by exporting an encrypted backup and opening it on the other machine. That file is the same envelope, so it needs the same passphrase and nothing else.
What this does not protect you from. Malware on your machine, a browser extension with permission to read pages, a shoulder, or someone who knows your passphrase. A browser-held vault is also as durable as the browser profile: clearing site data for this domain deletes it, and so does a private window closing. Take the encrypted backup.
Questions people ask
Where is the vault stored?
In this browser's localStorage for obscuraos.com, as one encrypted item. It is not sent anywhere, there is no account, and the page works with the network turned off. A different browser, a different profile, or a private window is a different vault.
What happens if I forget the master passphrase?
The vault stays encrypted and nobody can open it, including us. There is no recovery, because recovery would mean something somewhere holds a second way in. Write the passphrase down and keep the paper somewhere safe, or print it with PAPERKEY.
Does a wrong passphrase damage the vault?
No. A wrong passphrase fails the AES-GCM authentication tag and the page stops there. Nothing is written back to storage on a failed unlock, so you can try as many times as you like.
Can I check the encryption myself?
Yes, and it is the point of publishing the format. Copy the item out of localStorage and run it through any PBKDF2 and AES-GCM implementation: 600,000 rounds of PBKDF2-HMAC-SHA256 over the base64 salt gives a 32-byte key, and AES-256-GCM with the base64 IV over the base64 ciphertext gives the vault as UTF-8 JSON. Twenty lines of Python or Node will do it.
Which CSV exports does the import understand?
1Password, Bitwarden, LastPass, Chrome and other Chromium browsers, and Firefox, each recognised from its header row. Anything else is mapped by column name where the names are clear enough, and whatever cannot be mapped is listed for you instead of being thrown away.
Why does unlocking take a second?
Because deriving the key is meant to be slow. Six hundred thousand rounds of PBKDF2 costs you about a second once and costs somebody guessing your passphrase the same second for every guess they make.
Why does it lock when I switch tabs?
Because the common way a vault is read by someone else is that it was left open. The idle timer is yours to set, but the tab-hidden lock is not optional, and the cost of it is one passphrase entry when you come back.