Some evidence on multi-word passphrases
lightbluetouchpaper.org
lightbluetouchpaper.org
Ok, after reading a lot about passwords I decide that I'm gonna go with a condensed passphrase more than 10 characters long and with a couple service-contextual caharcters in the end. That oughta keep me safe right? Well, except I have to pick a 6-8 length password that MUST have a number AND a capitalized letter in it!
Part of the problem is that languages never standardized one password interchange format. It could be really simple. Here's one example:
13 ffH+5dfGr64h UYDpAQkrzmvI8fZhqtXQNqCGLouWn2edKowiyqTlzsg
This is an interchange format based on computing PBKDF2(HMAC(SHA256)) with 2^13 = 8,192 rounds and a salt of ffH+5dfGr64h, to hash the given password. The exact mechanisms aren't important here, what's important is that there is no portable primitive which does this.The closest that the above comes to being realized is a system called bcrypt. It isn't PBKDF2, but oh well: find a bcrypt module and use it.
What about hash collisions? Is there a good way to handle that?
But if each of these comparisons has a roughly independent chance p of sharing the same salt, like 1/2^72, then the number you need before you get towards a 50/50 chance is approximately p * N^2/2 = 1/2, or N = sqrt(1/p). If p = 1/2^72, sqrt(1/p) = 2^36 = 68.7 billion.
So a 72-bit random salt will make sure that everyone shares a salt with less than a billionth of your users or so. If you want even better, you might want to know that a salt doesn't have to be random, and you could generate them incrementally to get even more security. For example in Node.js:
var new_salt = (function () {
var counter = 0, buf = new Buffer(8);
return function () {
counter = (counter + 1) % 1e6;
buf.writeDoubleLE(new Date().getTime() * 1e6 + counter, 1);
return buf.toString('base64')
};
});
Now as long as I have fewer than one million new passwords per millisecond, there is no chance at all of two people having the same salt. (I'm sure Windows has timing issues so that this has to be much more than once per millisecond, but the point stands.)You asked about hash collisions in particular, and in the context of not having a maximum length. That's a little trickier of a problem. Yes, there exist attacks, particularly on MD5, which use a bunch of arbitrary output blocks to steer a hash to a particular value. But that usually requires a hash to be well-broken. In the case of SHA-256, you would need something like 2^128 user accounts before you'd map different inputs to different outputs. So you're protected from both: you ensure different inputs to the hash function and then you choose a hash function which requires too much work to generate collisions.
9rIqIiGByCzcWq
But, it may be considered too long by some services, or not complex enough by others (as it lacks special chars), or it can't begin with a number, etc. Adding special chars breaks it for some DB apps (oracle can't take some chars in the password). It's really frustrating that it's 2012 and there's no global ISO password standard (or something similar).
A random 5-word passphrase with three random characters tossed at the end has better than 82 bits of entropy and will halt offline attacks, at least by non-TLAs, for many years to come.
These are not hard to memorize. What's hard to memorize is 101 different passphrases, many of which you don't use every day, which is why the people actively working to make it easier are focusing on the management problem.
What it looks like in practice:
drostie@signy:~$ words -c 5 4
(Line entropy: 64.7055497954 bits.)
rebelliousness subpoenas garrulous coach
mono peroxide underused fathers
entreat entwined meatier umbilicuses
relay torrential husband Jenkins
Kristine sluggers feverishly Lessie
So each of those lines has a little over 64 bits of entropy. You might also consider the following one-liner in the shell: drostie@signy:~$ head -c 9 /dev/urandom | base64
ST2QpSb0eKHk
If you're not paranoid, consider typing "password" into DuckDuckGo and it will give you a random password. If you're slightly more paranoid, consider using mouse-movements to generate your own random password with a random tool I coded for making random API keys: http://code.drostie.org/api.html . Just truncate to the first 10-12 characters or so.Of course, password managers have their weaknesses (a compromised system will often give access to all accounts, rather than just a few), but it is far more secure than having people using the same trivial password for every service.
You can easily create a simple paper and geographically-redundant system (e.g. using a one-time pad) that means you can keep the passphrase in the open, for example, in your wallet or purse.
Password managers are the only way to go and eventually all password/passphrase users realise this because they end-up emulating these systems anyway (e.g. using extemely poor entropy additions to their existing passwords for different applications).
But really, if you write a password on a $50 dollar bill you're not likely to then stick it to your monitor or leave it under a draw. You'd keep it in your wallet, and you hopefully keep that safe. Once you've remembered the password you can destroy the bit of paper. (uh, not a $50!)
I'd be interested to see if there's a bias in words that are selected by people when using a diceware system. People generate a passphrase, but then say "I won't use the first word because I can't remember it, I'll just generate another word". Also whether that would lead to exploitable weakness.
I also would like to know whether there is a simple way to strongly encrypt a password that one keeps in one's wallet. The goal should be that if I am pickpocketed in a Dutch train (which seemingly never happens but the Dutch always warn me about it), my wallet does not contain some piece of paper saying "my.address@gmail.com h6tHVtcj3DsY".
This is a fine password. Long, easy to remember, and has five special characters.
This does break down like they said when you stop using coherent meanings. A passphrase that is HorseQuoteBulb would be hard to guess in comparison to HorsesEatHay or something of the same style.
The same goes for passwords: while it may be easy to guess a password as "phrase" it suddenly becomes a lot more difficult to randomly attempt guesses at "7_-Az!e".
Eventually I think we'll all be forced to use two factor authentication for added security. Here the user is mostly safe from their own ignorance where the danger of having credentials stolen is more prominent in the form of Man in the Middle attacks.
In my case, I use multi-word passphrases with words from a obscure dialect of a tiny European country's language. Being a dialect I grew up with, it has the benefit of being easy to remember, and the obscureness of it means the phrases itself are more or less a random string of characters to any brute-force attack. Not exactly a "best practice" for anyone but myself, but I'm happy with it :).