I'm nearly positive the US code salted the hashes (it's been a long time since I was in that code :). I say US code because (again, memory is dim) I think they had a partnership with a company in the EU and that (might have) included authentication.
The platform guys at Riot were the sharpest group of engineers I've worked with. Smart and able to get stuff done without bike shedding. They did stuff right.
It is possible to tell the passwords were unsalted because: "We compared encrypted password hashes and discovered that 11 passwords were shared by over 10,000 players each" and one of the points of salting is to make impossible to identify identical passwords from the hashes.
Not really. You get that with per-password salting, but having a single salt for your whole database is not uncommon. Since the main point of salting AFAIK is to ward off rainbow tables, it's better than nothing.
EDIT: As noted in the comments, the way I put this originally was kind of flip and misleading and I apologize for creating confusion. My point was that I've seen a number of places do it that way, so just throwing at at your problems doesn't necessarily fix everything.
A single salt for the whole DB is not salting. It is no different than a (custom) hash function, which does not prevent identifying identical passwords, and which does not prevent rainbow table cracking.
Preventing rainbow table attacks is exactly what a custom hash function would do. You can't precompute hashes if you don't know the hash function. But you're right that a single salt in conjunction with a known hash function generally provides little additional protection, although this depends on the size of the salt.
A few years back I started a project to create rainbow tables for Oracle hashes with friends. The old Oracle hashing algorithm was pretty weak, but used the username as a salt. Within a few weeks we had rainbow tables for lots of default oracle accounts.
Moral of the story is to use a unique salt per account, but don't roll your own crypto in the process.
Unique salts are absolutely the correct way to rainbow-proof a database of hashes. But a novel hash function will still do the trick and isn't comparable to using a single salt across the entire database, as you originally claimed.
Reverse engineering a novel hash function, while theoretically possible, isn't a capability possessed by the folks dumping passwords from LinkedIn or Riot. And even if it were, doing so would cost more than would be gained by compromising those passwords.
Thus, in practical terms, a novel hash function is a great way to undermine attackers, not unlike using Linux or opening files in non-standard viewers (LibreOffice, Nitro PDF Reader, etc.).
1. And if you have access to a good cryptographer, you should absolutely roll a novel hash function as well. Security through obscurity is the proverbial cherry on top of your defensive sundae, i.e. it's only a bad thing if you rely on it exclusively.
2. Not to mention that the whole point of rainbow tables is that they've already been computed. If an attacker has to reverse engineer a hash function to create a rainbow table, that largely defeats the rainbow table's purpose.
1. No. A good cryptographer will tell you to not re-invent crypto and to use existing peer-reviewed hash functions. This is why the NIST is hosting an open competition for selecting the future SHA-3.
2. This is exactly what happened with the custom proprietary "obscure" GSM A5/1 encryption algorithm. First it was reverse engineered (based on a leak), then David Hulton and Steve Muller created rainbow tables for it. The fact that it was a custom algo did not defeat the rainbow table's purpose.
There are many ways a custom hash algo designed by a company could end up being used across multiple of its password databases, and could subsequently be leaked, making the generation of rainbow tables possible and valuable (by rogue employees or hackers), that relying on the obscurity of a custom algo is a bad idea. As you recognized, salting is the ultimate protection. So there is no point in talking about alternatives.
Yes but it's not like the random hacker has a 600 gig rainbow table for MD5('DATSALT' + PW). If you REALLY want to do the right thing when it comes to storing passwords, you need to use a hash algo that is computationally hard enough to brute force, it should take at least .5 sec on a good computer to compute. Every couple years, you should add another pass of the algorithm, ie. F(F(X)), to compensate for faster computers. By adding the extra pass, you won't need the original password to generate the new, revised, stronger custom hash algo. If you do this, in 10 years your passwords will still be secured. Also, salt your passwords with each a unique at least 100 random bytes, shouldn't need to be said.
As long as the salt is added for each recursive iteration, it should destroy any kind of cryptographic hints given by hashing a hash. So you shouldn't be doing F(F(F(X))) rather it should be F(SALT + F(SALT + F(SALT+X)))
But anyhow, I was talking about increasing the security of an already-existing hash algorithm. Even if the recursive hashing isn't that much more secure, it definitely isn't less secure than one pass...
normally salt is some random string unique for each user, but you have to store the salt of each user in database for authentication, if your database is hacked and they got both your hash and salt, it is really no difference between salt and no-salt
Then the rainbow table can only be used with this specific site. This makes it no more efficient than brute forcing. You can store the hashes yes, but you can also include the cracked passwords in the dictionary and it takes only slightly more time to compute them even with unique salts.
Site-wide salting has almost the same security as per-user salt, as long as the salt is not leaked or cracked before the database is leaked for pre-computation.
A database-wide salt makes cracking the database as hard as forcing one password. You only need to do the computation once and then you have a super-quick lookup for all the other hashes. Per-entry salts totally bust that.
Technically yes, but don't use md5 for anything security-related ever. It's broken. http://www.mscs.dal.ca/~selinger/md5collision/ is just one example. (I also remember reading some years ago that md5s within md5s can make the resulting hash more vulnerable to certain attacks but I don't have any formal knowledge in cryptology to say for sure.) Use bcrypt/scrypt and you're automatically protected from both rainbow tables and brute force.
H(Salt . H(Password)) is a lot like an hmac (minus the secret part and the padding). I'm not sure about the pre-image vulnerability mentioned on wikipedia's md5 page, but as for collision vulnerabilities, according to wikipedia's hmac page, "HMACs are substantially less affected by collisions than their underlying hashing algorithms alone. Therefore, HMAC-MD5 does not suffer from the same weaknesses that have been found in MD5."
It's not salty enough for my taste. What you've done is no different than:
H(H(Password) + Salt)
If I steal your db and have another db that contains your user's unsalted password hashed with the same hash function, I can easily test if the same password is used in both places, simply by replacing H(Password) with the other hash. This leaks information and provides incentive to continue trying to crack the easiest target, if I really want what you have.
A simple change makes this comparison impossible:
salty = H(H(Password + Salt)
Now there's no place to plug in the other hash, so I can't tell if the accounts share passwords until I successfully crack one and try it on the other. I might not bother and focus on lower hanging fruit.
Always assume your salting method is public, even if you make attempts to keep it secret. And remember that your site isn't in isolation; your user and every site they interact with are also potentially weak links in the chain.
Note that the examples above are oversimplified. You should look to a better authority on how to properly store passwords. In a future leak, we'll be surprised that the sites involved only salted their passwords.
Yes, as long as you use some salt data that is unique per user (timestamp, random number/guid/whatever) (you have to store that obviously), then it's fine. The problem is acting as if a site-wide salt is an ok-thing. It's not.
Incidentally, as the guy who started this whole thing, I'd just like to note that I actuslly agree with this. When I said they were "OK" or whatever, I meant it in the sense of "I guess it's good they're doing something," not like I'd recommend it. Please nobody get that idea.
Really? They always seemed quite incompetent to me. Upgrades frequently took 3 to 4 times as long as planned. Unscheduled downtimes happened at least once a week. Matchmaking took forever even when servers were busy, and when asked about it on the forums, the developers described their matchmaking algorithm as one that ran in n!! time on the numbers of players looking for a game.
We can't actually tell much about their password storage mechanism from that post. For one, they mention "encrypted hashes", which might mean encryption, might mean hashes, or might mean both; for two, they don't describe how they determined which users had weak passwords. If they were using some kind of reversible encryption scheme, it's possible that they ran that function against their database and determined common passwords that way.
I'll give them the benefit of the doubt, unlikely as it may be, because if they were in fact doing something as stupid as SHA1 or MD5 or ROT13, and they still opened their post with "Keeping player information secure is very important to Riot", then somebody needs to be strangled as an example to other mealy-mouths.
I also take issue with telling your users what kind of passwords to use. If you're storing passwords correctly, and if you're blocking brute force attempts, it almost doesn't matter what password your users are using. (Almost: somebody could still try "password" on an account and get lucky if it's one of the 10,000 accounts with that password.)
No. God, I hope we don't find out they're use symmetric encryption. Do I need to explain why that's a stupid idea?
In case I do: 1) The site doesn't need my password in plaintext. 2) If the server is compromised, the attackers don't just have salted or unsalted hashes THEY HAVE FULL PLAINTEXT PASSWORDS (unless it's some weird case where they have DB but not FS access).
No, either way, they're wrong.
(Sigh, I'm sorry for the snippiness, I'm just tired of coming into everyone of these threads with people who earnestly try to regurgitate what they heard from the last thread about this and manage to give bad advice or implications.)
No, you didn't need to explain that. (I hear ya though.)
Yes, they are probably wrong. However, unlike the recent LinkedIn leak, at the moment we know almost nothing about how they were storing passwords. (Although, according to a thread on their forums, they did leave a user's previous and current passwords both simultaneously active -- not a good sign.)
I think that HN didn't used to so readily confuse speculation and facts.
A lot of game companies don't get valid email addresses from most of their user baseso if they don't have a good email to authenticate a password reset, leaving the old password active sometimes is the only option to authenticate users for a password reset.
Well, considering they said they compared "hashes" later on, and the hopeful unlikeliness that they were really using symmetric encryption, I feel like it's a pretty sure educated guess and not just a knee-jerk reaction.
edit: I didn't mean to be personally chastizing in my first post, I'm just extremely distraught at the advice I see in these threads, the continued confusion of people and the fact that people with massive userbases either aren't paying attention or are in this ignorant group of "it won't happen to me" people.
It says encrypted not hashed, these are not the same thing. Encryption uses keys and without the keys you can't get the value without a huge brute force effort. Hash without salt can be broken trivially. It'd bad either way but encrypted is way better than leaked hash.
I believe they mean hashed (as pointed out later in the article) but if it was encryption I'd disagree pretty strongly with the assertion it's safer than straight hashing.
If you don't need the original password, hashing should be used, not encryption. Hashing means there is no issue of key management as is the case with the encryption system. If those keys are mishandled then it's trivial to recover all the plaintext passwords.
Decryption would be difficult without the keys, but it's likely that (a) they have keys stored somewhere insecure or (b) they'd perform the encryption with a single key for all passwords. For (b), this means you simply had to have a valid account and you'd have a plaintext-ciphertext pair to bruteforce. Once that single key is extracted you'd have access to all the other passwords as well.
Despite the other reply you got (which was my original 'lol'), no, there isn't an advantage to salting a password that is going to be encrypted with symmetrical encryption. I mean, what would that even mean?
This way, even for the same password, there are different salts, and thus different hashes. No one can run a rainbow attack unless they've generated rainbow tables for that salt (frankly, it would be possible, but useless to generate a rainbow table for a specific salt)
I don't understand why this keeps happening. When someone designs the user/password model for a website or software do they serious not even consider properly encrypting the passwords? This is not rocket science, implementing a relatively secure password hashing setup takes a minimal amount of work. Hell, adding a salt is an extra field in the database, an extra line of code when creating a user and an extra "+salt" when computing the hash.
I honestly think they spend more time coming up with ridiculous password requirements than actually encrypting the passwords. Possible dialog:
Dev 1: The passwords must have at least one symbol, one number, no dictionary words, and it can't be longer than 15 characters.
Dev 2: That'll be pretty secure, which hashing functions should we use? And should we salt it?
Dev 1: I think MD5 should be secure enough and salts are just overkill.
To me, it adds insult to injury when companies that fail to take the most basic, well-known measures to protect their login databases always tell us how much they value the security of user information.
That would only be acceptable if the next words were, "and therefore we have fired the CTO and all programmers involved".
Is it just me or have the number of announcements on HN about password leaks gone up in the last few weeks?
I think availability bias is kicking in, with each additional announcement, more links about announcements are posted (for karma) or more sites feel like they can announce, under the cover of larger leaks, that they themselves have been compromised.
Looks like it's only the EU databases that were compromised, so if you have an NA account like I imagine most people here here would, no need to panic (though changing your password anyway won't hurt anybody).
That sounds like a really proffessional letter to their users. Brief, honest, precise, and they clearly state what their action items to prevent this from ever happening again will be. I like it a lot.
User generates a public and private keypair. The public key is given to the remote site (such as LoL or Linkedin), but the public key is not secret -- it is public. You can post it on your blog, whatever. You can use it for multiple accounts without concern.
The public key allows one to encrypt some data, but the public key cannot decrypt the data.
The private key can decrypt the data.
When the user wishes to log in the remote site, using the public key, encrypts a random string and sends it to the user. If the user manages to successfully decrypt this random string and send it back then the remote site can infer that the user holds the private key -- because only the private key can perform the decryption.
The private key is never sent to a remote party. Only meaningless random strings are communicated over the wire.
The (significant) drawback to this method is that the user will have to have the private key with them in order to perform the authentication. But perhaps mobile devices will solve that problem for us.
I would love to see an ssh-like key exchange built into browsers. You add your key to the site, GitHub style, and then you use that for auth. No more nonsense with OAuth or "remember my password" or the remote site having your password just because they grabbed the DB. It's just a useless public key to them.
Cryptographic hashes are "non-reversible" too. But they're both vulnerable to offline dictionary attacks if the attacker obtains the host's secrets -- which I think is what `astroduck' was really asking about, leaked server databases like this news story.
(I don't see how there's any possible protocol that behaves otherwise: if Alice is capable of proving she possesses a secret to Bob through a protocol, then Bob can always discover Alice's secret by playing that protocol with himself, enumerating every possible secret until the protocol succeeds. And so can anyone who knows everything that Bob knows about Alice's secret.)
The SRP paper doesn't say much about this except that brute-force dictionary attacks are "expensive". I don't think they make specific claims about computational hardness like scrypt. The paper was written in 1997.
"An attacker who captures the host's password file cannot directly compromise user-to-host authentication and gain access to the host without an expensive dictionary search."
"Security as a Service" that does what? Teaches you how to store data securely, explain to investors that user data was stolen or an outsourced password verification utility.
The first can be done if people would bother to learn and completely understand what they're doing (this thread and the corrections I've had to make seems to prove that people think they know what they're doing when they don't).
The second, have fun with.
The third is already solved. oAuth, OpenID, Facebook Connect, Twitter, BrowserID, etc.
All these sites have to do is store the passwords using bcrypt and with salts and they're pretty much uncrackable (as far as we know).
The reason they're uncrackable is because when using bcrypt it takes a second or more to generate a hash for a password (compared to 0.000001 seconds for md5) meaning if they want to try and brute force the password or build a rainbow table it'll take them years instead of seconds to crack each password.
There's no need to remote password storage, they just need to learn more about password security.
Federated identity doesn't replace passwords, it just punts the whole process of authentication to a third party. That third party will still need to authenticate the user somehow, which brings us right back where we started.
Keep in mind that the target audience of this post is a largely nontechnical user base. These days, average people are getting a general idea of the meaning of "encrypt" due to the prevalence of, e.g. SSL in e-commerce, but not necessarily the meaning of "hash". Thus, it's not uncommon that places will intentionally misuse these words in order to reach a nontechnical audience.
Good god, this topic is discussed to death and yet there are spreading very inaccurate, insecure crap in this thread. I think everyone needs to stop giving advice and speculating about what is "good" and defer to a security expert or a set of codified best practices. I just don't understand how some people seem to understand salting, hashes or encryption but not enough to understand why unique-per-user salts are important, why asymmetric and symmetric encryption differ or why encryption has nothing to do with this style of password storage. If you don't understand these things, stop giving security advice in these threads.
>but not enough to understand why unique-per-user salts are important
I don't think that's been covered in this thread. If the main point of salting is to make rainbow tables ineffective, a single DB-wide hash still does that. Presumably if a hacker gets a copy of your entire database, they still don't have a copy of your hashing function with that salt. So then they're reduced to brute force.
Something else that I just thought of is, if you're salting per user, where does that salt get stored? A secondary database?
..And then come to find out it's been discussed down thread. Oops.
Any competent security architect will assume that if the bad guy gets a copy of the entire password database he also gets a copy of the entire codebase, all design documents, installation instructions, and operations manuals, and designs the system to be secure against that.
To whomever downvoted me, I've seen people suggest on this thread or ones in the last 24 hours that:
- symmetric encryption is appropriate for sites' storing passwords
- md5 is okay
- site-wide salts are just as secure as user specific salts
and more. Some of these were suggested by people that have far, far more karma than me. Some were suggested by people that had had this explained to them in previous threads and then took it upon themselves to mis-convey this information back. I don't have a pony in this race as I use different strong passwords per-site and I don't have user data to worry about. I just cringe everytime I see potential hackers reading this misinformation or hackers potentially with data who don't understand their risk or blindspots. I only mean the best, even if I come off exasperated.
I mean sure, if you can get access to one password, you will be able to predict passwords for other websites, however, these SALT + WEBSITE-passwords tend to end up very, very long, which makes it very hard to break. Afterall, every single password you listed there is at least 13 characters long.
Anything special happening? Is it Friday 13 and stoner dot something again? Heck even the kitchen computer at my grandmas house may have been target this week... Hopefully that one had salt. Tum dum tiss.