views:

1061

answers:

7

I am developing on a LAMP(erl) stack and know of several ways to store obscured passwords. I'd like to hear from those who feel they have a best practice, given MySQL 4.1.1 and Perl 5.8, and the reasons why it's the best.

One option I have read about, using the MySQL ENCODE() and DECODE() functions, sounds pretty good to me... your thoughts?

+3  A: 

Well, since there's a DECODE() function, I'd say no, for the simple fact that you probably want to store the password in hashed form, to prevent anyone obtaining your database/password file from casually reading passwords.

I'd recommend going with the classic salted hash method.

Rob
encode/decode can be salted.
benlumley
Rob is right. You want an irreversible hash on your password. Being able to recover a password plaintext means your system is inherently weak.
Wouter Lievens
That's not salting; you pass in a key used to encrypt/decrypt. Salting a hash changes its value and helps protect against brute-force methods of generating collisions, by having a value that's different per user, and thus increasing the time to obtain a single password.
Rob
But the existence of decode means that once you've hacked into the database server and got all the encoded passwords, you can trivially decode them. Whereas your password field could be SHA-256(Username + ":" + salt + ":" + password) or combinations thereof. A dictionary attack is much harder.
JeeBee
+1  A: 

I'm not sure what these functions do, but for passwords in a LAMP stack website, I'd definitely use a salt field as well.

Your user table would have:

  • name
  • pass
  • salt

The plain text password is then encoded using some encode function on a concatenation on the plain text password and the salt. This result goes into the pass field. The salt is stored as well. That way you can verify plaintext passwords when the user logs in. The salt can be anything, the longer and more random the better, but I don't think it's that sensitive.

This improves security vastly, because now your users don't use 5 letter passwords anymore, they use 5+len(salt) size passwords, and if the salt is big enough, no rainbow database will ever contain your hashes.

Wouter Lievens
Using a secure hash is much better than using a salt.
Brian C. Lane
Using a secure hash and a salt is better still, which is how I understood this answer.
Max Lybbert
+5  A: 

If you only need the password to authenticate yourself/the user, a one way storing (like md5) is better.

Burkhard
Best to try an actual secure hash (SHA256, SHA512), not a secure hash from 10 years ago. Practical attacks aren't there yet, I know, but that's no excuse to still use it.
Vinko Vrsalovic
+7  A: 

Generally, I prefer to keep passwords as hashes that can't be recovered, rather than as encrypted items that can be decrypted.

By computing a hash from a visitor-supplied string(plus some salt, of course), I can tell whether the user provided the same password twice, without the security risk of allowing my application to be able to decrypt the provided password, possibly maliciously.

My sense is that encode() and decode() are probably good solutions when you want the data to be recoverable, but that unrecoverable hashes (using Crypt::MD5) is a better approach for stored passwords.

Tim Howland
Best to try an actual secure hash (SHA256, SHA512), not a secure hash from 10 years ago. Practical attacks aren't there yet, I know, but that's no excuse to still use it.
Vinko Vrsalovic
+6  A: 

I think a salted hash with a proper hash function like SHA-256 is the best. Passwords that are reversible are not as safe as those who cannot be reversed. Without an external Perl module, you can use instead the built in SHA1() function, not as good as SHA256, but better than ENCODE/DECODE.

Additionally, you have to consider the path from your code to the database, which can be sniffed. You can avoid that risk by hashing in the code or by encrypting the database connection. Better to do it in code, because even when encrypting the connection there is still the risk about query logs being configured thus storing plaintext on a log file somewhere.

Vinko Vrsalovic
Lots of good answers here, thanks all. I ended decided to do the encoding/decoding in Perl after much deliberation, using perhaps Crypt::MD5, based on this comment from Robert Nice in the MySQL documentation, here:http://dev.mysql.com/doc/refman/5.0/en/encryption-functions.html#function_password
Marcus
Robert Nice has a nice point. Also, try to use SHA instead of MD5.
Vinko Vrsalovic
+2  A: 

Some applications require the user's password to be retrievable, as opposed to a system where the user's password is randomly reset to something, if forgotten (because it cannot be decrypted, because you're using a hash). In this case, encode and decode are OK, but why not use the built-in AES_ENCRYPT and AES_DECRYPT functions instead?

Also, keep with the suggestion of using a salt value, whether you hash or encrypt. It's beneficial in both scenarios.

Chris
In such situations I recommend having two passwords - the user's online password, and the 'telephone' password. Too many poorly developed systems store passwords unencrypted (and having the decryption key in the webapp means it is decryptable) or worse, sends them in emails! EMAILS!
JeeBee
With all do respect, the concern over password security, while warranted to a degree, is incredibly exaggerated. If you're that concerned about someone getting a hold of your database, you have other security issues to tackle first.
Chris
A: 

If you can decrypt a password, your security is flawed. You should always hash the password with a salt, MD5 is popular but there are superior hashing such as SHA and SHA-256.

TravisO