Filed in: Writing.PasswordScheme · Modified on : Mon, 01 Aug 11
Passwords have always bugged me. In an ideal world, we'd use them a lot less, and people would implement their usage properly, securely, and consistently. Unfortunately, this is not the case by a long shot. There are numerous flaws in the ways password systems are implemented, and this shifts the burden of ensuring security onto me, the user.
This page documents my attempts at a way of generating and storing passwords for various services. I'm currently using this scheme, so I leave out particular details that should be kept secret.
Herein, I focus mostly on websites.
Leakage is when the user reuses passwords for sites, one of those sites is attacked and has a plaintext password database which is compromised. Thus, this password can be used to access other sites.
Use a password generation method, and record the method used instead of the actual password. My methods tend to be complex enough that a human would have a hard time doing it themselves, but simple methods would be possible that are doable by hand.
By using methods, we are able to work around the problem of different sites requiring different character classes, lengths, etc. We can reuse methods for different domains, provided one of the inputs to the method is the domain itself (or some other aggregate that is unique).
I use a Python script to store, retrieve, and execute the per-site methods. The database of methods is a list of dictionaries that look like this:
url and username simply identify the site.
password is where the magic happens. It's a lambda function that returns the password when called.
pwdhash is a function defined elsewhere that hashes a domain/password pair, as implemented at https://www.pwdhash.com/. This ensures that we can reuse our passwords at different domains without fear of password leakage.
seeds is a list of password functions. They would essentially be the same as a traditional password database (like Lastpass), but implemented as a function that allows the user to enter it. The real seeds list exists only in the user's memory. I use a few different seeds that I have memorized. You could use just one seed for everywhere, but I like to have some compartmentalization between different notional classes of sites (email vs banking vs Facebook), just in case I accidentally leak the seed itself.
The idea behind this is that you can use any password method at all that is expressable in Python. For example, I used to have a bank whose website only allowed 8-12 alphanumeric characters as a password (!). We could use a theoretical pwdhash function that took a third argument to specify the characters to use, and trim the result to 12 characters: