From a security standpoint, there is no difference between storing the password in plain text, and storing it encrypted with the keys on the server to decrypt it. It's like saying that having an unlocked safe is not the same thing as having a locked safe with the keys left in the lock. Why should the OP make the distinction?
Because there is a difference. Sure, academically, and positing an ability to break into anything, encrypting the passwords and retaining the key is useless. But realistically, I can think of a few ways off the top of my head where the difference might matter.
For example, you could have a dedicated decryption server holding the server-side key, carefully isolated from the rest of the internal network, its only channel of communication a single socket with request/response on decrypting passwords for password recovery. It could have rate limiting built in, and a storm of alerts to go off if backends request too many decryptions.
Sure, I think everyone on HN agrees that any type of security has its weakness. What we are discussing here is whether 37signals is inadequately handling users' data by storing passwords in plain text, and the argument is that there is no difference in the level of security of "encrypted" passwords if the server has the key to decrypt them.
In other words, even if the author found out before writing the article that 37signals was storing users' passwords encrypted (instead of hashed), then he still would have written his article, and we would still be just as concerned as we are now.
You seem to be arguing against a point that no one is making.
But encrypting the passwords with a key on the server is an additional "layer of security" that doesn't actually making it harder to crack. You're just adding complexity for naught.
It prevents you from getting the passwords with an SQL injection attack (or by reading the users.txt or whatever storage is used for the user list), so it does add protection.
layered security is not the answer - if the weakness is elsewhere in your application then potentially passwords can be extracted in other ways (people run straight to SQL injection as the main source but any decent cracker will be able to explore other options).
Hashing and salting a password removes absolutely ewvery security weakness in terms of directly extracting the password. No need for layered security and potentially complex uneeded encryption/decryption in your app. Safe, secure. end of the matter :)
"Hashing and salting a password removes absolutely ewvery security weakness in terms of directly extracting the password. No need for layered security and potentially complex uneeded encryption/decryption in your app. Safe, secure. end of the matter :)"
It is seriously worrying that you believe this.
Cracking hashed passwords offline is no big deal on a single machine unless you have really strong password policy - you know, the type of password no real regular user would even enter.
you think? I'll give you a 4 character password correctly salted and hashed with Sha1 and would like to see you crack it ;)
Allowing password security to depend on what the user enters IS silly - but who would! 32haracter salts and sha256 is going to produce a fairly uncrackable password.
Even if you know the salt and the salting algorithm (because simply appending a salt is also silly) it can still take a while :)
Im not talking about just sticking "MYSECRETSTRING" on the end of every password and sha1-ing it :)
The hash algorithm used is sha1. The salting scheme uses a randomly generated salt and a known salting roation.
I gave you 4 to give you fair chance to work on them. I'll give you more if you want. (there is no way to brute force these BTW so dont really bother :))
So basically the algorithm is in the code, so anyone who has ever seen the code knows the algorithm, which you can't change after you have actual users. Any ex-employee could take a copy of the verify function and a dump of the database and hack it home. Similarly a cracker who gets a DB dump of the passwords will probably get your code too.
Running sha1() in PHP on each of the 98569 words in /usr/share/dict/words takes 1 second on my laptop. Appending all of the numbers 1-100 to each of those, not surprisingly ups the time to about 1m40s. You'll probably get quite a lot of users with passwords like that.
Yes but that's NOT the issue were discussing here is it. You take steps to hide the algorithm from as many people as possible etc. It's not that hard to do.
Finally in a RL scenario I would use the password itself to generate the rotation schema. Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach. The way to do this is to generate a completely random salt and then use the password to create a scheme to rotate the salt into the password. Then hash the result and use the known pattern & the password to generate another scheme to rotate the salt into the hash.
The advantage of this is that even if you have a the hash you cant just pull the hash out of the string and append the salt onto every password in your list & then hash it. You have to reverse engineer the salted hash for EVERY password substantially adding to your decryption time. Because the salt is also pseudo-randomly generated it also means that you have to attack every password in this way - you cant pre-generate all the possible hashes and test them because I have basically ignored what the user has entered and increased the keyspace up to around 8e+24. Even the brute force mechanism has a hurdle to overcome because the keyspace assuming an 8 char password is 2821109907456. (there are yet other steps to take to overcome the dictionary style attack)
Add in the requirement for the user to enter at least 8 characters at least one of which is a number and your making it a VERY bad day for a would be cracker :)
Yes, this was my original point:
"Cracking hashed passwords offline is no big deal on a single machine unless you have really strong password policy"
i.e. if you allow users to set something weak as a password like a dictionary word then it doesn't matter what salting method you have, since you can try them all pretty quickly. (Probably saying "really" was pushing it a bit)
I've seen salting on it's own doesn't work since 'John the Ripper' (http://www.openwall.com/john/) can go though a password file that has a different salt for each user and find some passwords in a few seconds. It doesn't have rainbow tables, it just tries a given password with all of the different salts and compares them. This is why you also need a strong password.
You said:
"Allowing password security to depend on what the user enters IS silly"
and now you are saying:
"Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach."
Now you are saying a salting combined with a strong password policy is the solution and not either in isolation. Which I agree with.
Two way encryption would be an explanation to this, so I am waiting on what 37s' answer to this blog post.
It's sad people quickly come to conclusions when only hearing one side of the story.