"You must use one of these special characters: %^&*()"
This is what your scheme doesn't address.
- You have to keep track of n for every site.
- If the master password is compromised, you have to change each password manually.
- Not well-integrated with browsers.
- Far less convenience on a phone.
I consider this far better than having to keep a password manager's database. n = 0 for the vast majority of sites without sensitive personal data. For the small handful that need to change, I usually sync them all to the same value of n about once or twice a year.
> - Not well-integrated with browsers.
I use Chrome's password-saving feature for websites that don't store sensitive personal data. For websites that I consider sensitive, I actually like that it isn't integrated with the browser.
> - Far less convenience on a phone.
This is true. If my laptop can act as a bluetooth keyboard to my phone it might make life easier.
- If last few recent n's don't work, I just reset the password to the most recent n.
- There are browser extensions
- There are apps, and my web UI (https://ph.leftium.com) works OK (and a bookmarklet adds more convenience)
[1] https://boingboing.net/2014/02/25/choosing-a-secure-password...
Keep in mind that most password managers also encrypt your password database with your master password, so my solution isn't any worse than those.
Memorizing a even a 16-character (upper/lower + symbols) random string as your master password would be 16*6 = 96 bits of entropy which is more than enough.
Dealing with memorizing ONE good 16-character random string is within the abilities of most people. Dealing with multiple ones is what is hard.
For me, playing around with hashcat, was an eye opening experience and I truly believe in the Schneier quote from above.
When an attacker acquires a leaked database, they're not cracking high entropic passwords.
Also, a character has at most 8 bits of entropy, not 64. If you use base 64 its only 6 bits of entropy. 16 x 6 = 96 bits is still more than enough though.
A downside if everyone used this scheme would be parallelized attacks on reversing the hash for the key. If you find a key that, with this scheme, creates a password for your service, you found the corresponding secret key. This then compromises all of that users passwords.
I actually am not a fan of 2nd-factor authentication (e.g. phone). If you lose the physical thing or it gets leaked to a stranger, gunman who mugs you, leaked by security holes in the thing's own embedded OS, it's no longer helping your security. I'd rather authentication depend on only what's in my mind and body and nothing external. Also, I lose stuff and forget stuff pretty easily, so I often just avoid carrying anything.
Randomly choose 6 words from a 10k English dictionary and you're set. Hell, make it 12 words. Still insanely easier to remember than a 12 character alphanumeric/symbol password, and much more difficult to crack.
It has 50,105 words. Gets you an extra 2.3 bits per word.
Not exactly true if they are separate words. In a word-based password scheme, you are treating entire words, not characters, as units. The chance of fire, truck, and firetruck appearing in one password in that sequence, given a 10K word dictionary, is 1/(10K^3). The miniscule possibility of this speaks to the fact that there actually is a large entropy.
"green rubber yellowed out inside the 1st horizon"
I make random passwords like that (though usually 6+ words) all the time. I admit I can't remember all of them, but I can remember up to ten or twelve. Which is enough passwords to cover all the important services I use.
The big pain with that is that some services don't allow more than N characters for passwords (looking at you, 20-characters-limit-PayPal), some services don't allow spaces and whatnot, so you have to adapt.
Plus, you should enable 2FA wherever possible. You don't really need a super strong password once you have 2FA, so for those cases you can resort to OP solution of having "master_password + 'whatever' + domain" with master password being one of those ten you can actually remember and not even having to encrypt the whole thing.
I've got to offer one on my website (gimme all your passwords, mwahahaha!)
Before reading this I was convinced that stateless deterministic approaches like these was the ideal. But some arguments in that post changed my mind.
16 characters + 'Aa$1' has universally satisfied every website I have used to date except Baidu (which imposes a maximum of 16 characters total on passwords). The number of exceptions to this is probably miniscule.
> Deterministic password generators cannot handle revocation of exposed passwords without keeping state
That's what 'n' is for. Either you can keep 'n' as a state variable which is much easier to manage (and if you lose the file, you can try a few values of n and get yourself back into those websites without much hassle), OR sync the values of n every several months on the sites that use it.
> Deterministic password managers can’t store existing secrets
This is orthogonal to the password problem. I store sensitive files that aren't passwords in a GPG-encrypted tarball on Dropbox.
> Exposure of the master password alone exposes all of your site passwords
This is true of stateful password managers as well, if you backup your database on anywhere insecure or any device (e.g. laptop) that could potentially be mugged at gunpoint, confiscated by border control, leaked by buggy software, etc.
# requires: sudo apt-get install xautomation for 'xte'
import time
from subprocess import Popen, PIPE
macro = ""
for char in password:
if char == '$':
macro += "keydown Shift_L\nkey 4\nkeyup Shift_L\n"
elif char == '+':
macro += "keydown Shift_L\nkey equal\nkeyup Shift_L\n"
elif char == '/':
macro += "key slash\n"
elif char.isupper():
macro += "keydown Shift_L\nkey %s\nkeyup Shift_L\n" % char
elif char.islower() or char.isdigit():
macro += "key %s\n" % char
print("Entering password in 3 seconds ... [^C to abort]")
time.sleep(3)
Popen(['xte'], stdin=PIPE).communicate(macro.encode())One of the biggest drawbacks of this approach is that you are stuck with your master-password. You can't change it without modifying those for all the websites.
I also keep a list of the "domains" along with plaintext comments for each of them (username, email I used, etc) that are not strictly required (so still portable) but just make it a little more useful when it's synced.
The big downside I've found is lack of apps. Sure it would run on any phone, but I haven't managed to get it to run on the phones conveniently. So if I'm without a laptop right now for the most part I'm locked out.
[1] https://github.com/passwordly/passwordly-python/blob/master/...
"Your password is too long"
So I needed some additional piece of information, namely how many times I've had to change passwords, so a new function argument.
Eventually I gave up and started using a password manager.
This is unlike a stateful password manager. There the security of the system is related to the strength of your password + the strength of the security of the place you store your password db. If you pick a place that is serious about security, your almost certainly better off. Critically, a compromise of some random forum you signed up for doesn't impact the security of your bank account in any way.
Not exactly. It's equal to the strength of your master password only. Even if one of your passwords leaked, this function does not compute fast enough in the forseeable future to brute force your master password, as long as your master password is strong.
> And GPUs are pretty good at brute forcing PBKDF2 - so it has to be really strong.
Interesting, thanks for telling me this. But how much better? I mean, a GPU with 1024 CUDA cores surely cannot surpass 1024 CPUs. So all we need to do is bump up 100000 to a slightly higher number to make it GPU-proof if that's the case, no?
> There the security of the system is related to the strength of your password + the strength of the security of the place you store your password db. If you pick a place that is serious about security, your almost certainly better off.
The problem is that it's difficult to find some places that is serious, and that you trust to be serious. Most people will end up putting it on Dropbox or Google Drive because there isn't anything else that is accessible to them and easy to use on a phone. Also, what if you're on vacation, PC rendered in an unbootable state, and you need to reinstall your OS? This has happened to me at least 3 times.
The weakness of PBKDF2 is that it requires a small fixed amount of memory to run, making it ideal for brute forcing with a GPU. Algorithms like Scrypt / Argon2 are designed to counter this by requiring lots of memory to run. Best reference I could find or current best GPU brute forcing speed is https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a27... - which seems to say that the test system could do like 100-200k password guesses / sec with PBKDF2-Sha256 @ 100,000 iterations (extrapolating from the numbers given).
The arithmetic then looks like this:
(7776 ^ 6) = 221073919720733357899776, because there are 7776 words in the diceware list.
(7776 ^ 6)/(10^12) = 221073919720 seconds to try all such password if the imagined hardware accelerated hash cracker can do one trillion hashes per second. In years this is:
(7776 ^ 6)/(10^12)/(365 * 24 * 60 * 60) = 7010 years.
So on average, it will take about 35 centuries to brute force the password when using hardware that can try one trillion guesses per second.
You are using "n" to differentiate from multiple accounts on "domain", right?.. or am I misunderstanding?
I suppose I could also do it as master_password + '/' + domain + str(n) or something like that.
Edit: nevermind, this would prevent you from retrieving the password - I had in mind a password generator, sorry.
For consumer use cases, you should use sources of noise for this, such as microphone noise, mouse movements, fluctuating voltages, etc. If you wanted to be super-secure you would use a quantum random number generator, which is truly random, but unnecessary for the threat models of most consumer uses. Just use anything but date/time. The random number generators of most modern languages and operating systems already have such measures in place.
domain = domain name for the service in question, e.g. 'facebook.com'
n = the nth password being generated for the domain (typically 0)
The 'Aa$1' is to ensure satisfaction of stupid password rules on various websites.
Advantages:
- Open source. You don't have to use some random person's password manager software that you have no clue how or where the passwords are being stored or the trustability of the people who wrote the software.
- Portability. You can run this on any OS including a phone with a Python implementation, and it's pretty easy to port the above to any other language with a hash library.
- No files to lose. You don't need to worry about losing a password manager's database, you don't need to worry about syncing the database across machines, and you can compute the above on any machine that you own and trust. Kernel panics while you're on vacation? No worries! Reformat your PC with a fresh Ubuntu install and compute the above to get access to your bank account, plane tickets, and e-mail again.