Code Monkey home page Code Monkey logo

passman's Introduction

This password manager is a standalone HTML file that contains some encrypted data, as well as tools for querying it, manipulating it, and saving the manipulated data.

This approach has some pluses and minuses. On the plus side:

  • It's super-portable; on any computer with a modern browser, this will work out of the box, without installing anything or using any tools you're unfamiliar with, or depending on any other files at all. (Contrast with: GPG.)
  • It's super-simple. Your passwords are stored as a simple JSON object, serialized and encrypted with a standard, widely-supported stream cipher (specifically, AES-256 in GCM mode, the key computed by PBKDF2-ing the SHA-256 of your master password). You can trivially export all your data as JSON; and if this page "just stops working" somehow, you can easily recover your data using a text editor and a Python script (see "I can't recover my passwords!" below). (Contrast with: everything that's not GPG.)

And on the minus side:

  • It's kinda ugly, as you see. Good UIs require require big ol' libraries and lots of elbow grease; I prefer minimalism.
  • You can't "save a file," per se, only download a copy of this file with the new passwords embedded (encrypted) in it. This is an unavoidable consequence of JavaScript sandboxing, and it makes version control kinda a hassle.

Conceptual Model

You have many accounts, and many secrets for each account. This password manager stores this as a two-level JSON object, like

    {
      "amazon": {
        "email": "[email protected]",
        "password": "pw-for-amazon",
        "username": "[email protected]"
      },
      "facebook": {
        "email": "[email protected]",
        "password": "pw-for-facebook",
        "username": "[email protected]"
      },
      "github": {
        "password": "pw-for-github",
        "username": "leethacker"
      },
      "more...": {"...": "..."}
    }

It's a little bad if bad guys get ahold of the account/field names (e.g. github or username); it's disastrous if they get ahold of the values (e.g. pw-for-amazon). This password manager is designed to somewhat protect the account/field names (they're stored encrypted on disk, but still displayed on the screen), and energetically encrypt the field values ("secrets") (they are encrypted on disk, never displayed on the screen, and they only ever leave the JavaScript interpreter's memory in plaintext by being copied to the clipboard when you ask for them to be).

At any given time, this password manager has one of these two-level objects, in plaintext, stored in "working memory." This is the object that you query and modify. It starts out empty; you can add/modify values, and "save" it by embedding an encrypted copy in a copy of the Passman file (remember, JavaScript can't just write to disk; it can only download new files).

There is such an encrypted message embedded in every Passman file. You can decrypt that encrypted object and merge it into working memory by typing the decryption password into the top-left password field, then hitting "Decrypt". (Go on, try it! The default password is "master".)

Tutorial

Here is a typical session I have with this file:

  1. Open the file in my browser.

    screenshot

  2. Type in my decryption key, and hit Enter.

    screenshot

  3. Go about my life.

  4. I need to log into Facebook. I type in queries to specify my "password" for "facebook", and hit Enter.

    screenshot

  5. I successfully log into Facebook. Heartened by my success, I decide to add my Expedia account to my password manager: I go the the "Modify Working Memory" pane, specify that I want to set "expedia"'s "username" to something, and hit Enter:

    screenshot

    I do the same for my Expedia password.

  6. Eventually, I close the page-- oops--

    screenshot

    That's right! I haven't saved my Expedia password. I hit "Stay on Page".

  7. I type in my password to encrypt the file-- oops--

    screenshot

    I must've typoed my password. I type it again:

    screenshot

  8. Before I forget -- I hate this step, but I don't yet know a way around it -- I move the newly downloaded password file to replace the old one, so that when I open it next time, I'll be sure to open the version that contains my Expedia password.

  9. Now I close the page.

I can't recover my passwords!

Don't worry! If the Passman page somehow stops working for you, you can use this Python script to recover your passwords: in a terminal, just run pip install cryptodomex bs4 &amp;&amp; python recover.py html < /path/to/passman.html.

If even that doesn't work for whatever reason, you'll have to roll up your sleeves and code a little. What you need to know:

  • There's a JSON object inside the HTML element with id="encrypted-message". It specifies a keyDerivationAlgorithm, an encryptionAlgorithm, and some ciphertext. All the arrays of numbers from 0 to 255 represent bytestrings.
  • The keyDerivationAlgorithm describes how to turn the decryption password into a cryptogaphic key: for the foreseeable future, it uses the PBKDF2 of the SHA-256 of the password, with the keyDerivationAlgorithm JSON object specifying the salt and number of iterations.
  • The encryptionAlgorithm describes the cipher used to encrypt your passwords. At time of writing, it uses AES-256 run in Galois/Counter Mode (GCM), with the encryptionAlgorithm JSON object specifying the IV (iv).
  • The ciphertext contains the encrypted message, and the GCM authentication tag. The tag is the last 16 bytes, and may have to be separated from the ciphertext depending on your crypto library's convention.

So, to decrypt:

  • UTF8-encode the decryption password, SHA-256 it, and run that through PBKDF2, with the salt / number of iterations specified by the keyDerivationAlgorithm
  • Take the ciphertext, and decrypt it with that key, using the algorithm/IV defined by encryptionAlgorithm. (You may have to slice off the last 16 bytes if the cipher is in Galois/Counter mode.)
  • You're done! That's the UTF8-encoded JSON string containing your passwords.

passman's People

Watchers

James Cloos avatar Justin Pearson avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.