views:

176

answers:

7

Question says it all, should passwords be stored using 2 way encryption or just 1 way?

A: 

Whatever - the important thing is that the decryption key is held securely and independently of the data - that implies asymmetric encryption which is computationally very expensive - and there's usually no significant benefit compared with a hash + secure reset mechanism.

symcbean
I (and many others) don’t agree. There is usually no reason to store passwords in a retrievable fashion.
Konrad Rudolph
I disagree 100%. If someone compromises your server, they can get the decryption key (and the stored encrypted passwords). So if your server is ever compromised, you just handed them the passwords of every user. And since a fair number of users use their user name and password for other things besides your site, you just handed the attacker everyone's online identity...
ircmaxell
@Konrad: unfortunatelly there are reasons: integration (need to use password to connect to another system) or the ability to send users their password. For the former you are often stuck; for the latter it can be a business requirement beyond your control (I prefer generate new password and set "must change after use" for this). In practice if possible use a one way approach based on a per password random IV + password and then apply good hash repeatedly -- no need for a key.
Richard
No, there's no intent to use RSA or other asymmetric encryption. The OP was a bit muddled on this issue.
Steven Sudit
@Richard: Integration is the only legitimate reason to store a password, and even then, it should be avoided if at all possible.
Steven Sudit
Did any of you actually read what I wrote before attacking?
symcbean
@symc: As it happens, I didn't attack you, and even gave you an upvote. However, I don't know where you got the idea that asymmetric encryption was even an option.
Steven Sudit
Although its more usually applicable to other authentication tokens (e.g. credit card numbers, root CA certs) there are lots of applications where, for various purposes, it may be neccessary to retrieve the original data - but as I said, these situations are very unusual and the decryption keys should be kept very safe.
symcbean
+10  A: 

Passwords should be stored via a salted hash. Encryption implies that you essentially want to/are able to decrypt it. A one way hash is best, then you can simply compare your existing hash to the one that the user uses to login or whatever the task.

Point is... one way hash.

Edit: As per Stevens comments. The following RFC 2898 covers some crucial hashing techniques. It also makes for a thumping good read.

Russell Dias
There are no 2-way hashes. And although you're very right to mention salt, we should probably recommend HMAC for mixing that salt in, as it blocks extension attacks.
Steven Sudit
+3  A: 

One way hashing is the way to go. I would not be happy if somebody could decrypt my password if he somehow gets access to the database it is stored. It's a real security issue if it is possible to decrypt passwords.

Just always save a hashed password and afterward compare the hashed input with the hash in the database. That's by far the most common and most save basic authentication method.

Stegeman
This isn't wrong, but it's very incomplete. It should mention salting, appropriate hashing algorithms, HMAC and probably strengthening.
Steven Sudit
+1  A: 

They should be stored using a one-way encryption (or salted hash function) whenever possible.

Situations where it might not be possible are cases where your application needs to use a password to log in to an external system (such as a database) that only supports plain-text authentication. In that case, you need to be able to decrypt the password in order to log in.

But, if you're talking about how you should store the passwords that users use to access your application, one-way encryption/hash is definitely the way to do it.

David Gelhar
Ok,I'll say it again: there is no one-way encryption. Hashing is one-way.
Steven Sudit
@Steven: I think the reason everyone is saying "one way hash" is to emphasise the point that they are one way, not to imply that there are two-way hashes. :)
Spudley
@Steven well, asymmetric encryption where you possess the public key but not the private is arguably "one-way encryption". Not that you would actually want to do that for password storage of course....
David Gelhar
A: 

Hashing is a random string, encryption is obfuscating a string that could then potentially be decrypted.

However, with hashing, it's also possible to produce collisions. It depends on your needs. If you think you need to re-gain the original string then encrypt the password. If it's just for user's passwords, then hash it. You can easily generate them a new password if they forget their current one.

Martin Bean
Hashing is not random. It is fully deterministic, in that the same input yields the same output each time. A large hash (SHA256, for example) on a small number of small strings (say, a few hundred thousand 12-character passwords) is not at all likely to have collisions, but even if they do, it doesn't really matter. It doesn't matter because salt prevents the same passwords from yielding the same hashes, making rainbow tables pretty much useless.
Steven Sudit
+1  A: 

Stretch and Hash your passwords. If you're lazy, just go with phpass which is used by Drupal and phpBB.

Arkh
Interesting article.
Steven Sudit
A: 

Now if you was storing some data that you was passing over a network that MAY be intercepted then you would use Encryption/Decryption

If your talking about credentials in the manor of password of a user then Hashing is the way to go.

The deference is that when you say Encryption you instantly have the retrievable side as well Decryption, With hashing you don't need to retrieve the value of the compiled text, just mealy check it against another hash

You can combine the the both together for transferring data across the web, but they still stay the same, just use each other to validate each other.

An example of how you should hash in PHP is like so:

The Hash

define('LOCAL_USER_SALT',£F$%^GH*&^%HG&*^%F&*(K(*');

Then this Hash should never change, this is what static hash and would be used to tripple hash a password, let me show you

class User
{
    //..
        function AddUserToDatabase($username,$password,$meta = array())
        {
            //Create a db salt
            $salt = md5(uniqid() . microtime() . $username . microtime(true));

            //Now we create a hashed version of the 
            $password = md5($password . $salt . LOCAL_USER_SALT);

            //Then you would insert the $salt and $hash to the DB
        }
    //..
}

After reading the comments, you can check like so:

class User
{
    //..
        public function CheckCredentials($username,$pass)
        {
            //Get results from DB where $username is set in the column
            //lets say $db_row is the data from the sql query
            $check = md5($password . $db_row['salt'] . LOCAL_USER_SALT);
            if($password == $check)
            {
                //The user exists.
            }
        }
    //..
}

So this is called 1 way hashing, there's no need to have a reversible algorithm for your users credentials.

RobertPitt
Better to use HMAC than concatenation, though.
Steven Sudit
Also, MD5 is broken, even practically. Use at least SHA256.
Steven Sudit
I have used SHA1 since writing authenticated websites and applications, and can honestly say I've never had a security breach.
Martin Bean