Related
I'm developing a PHP web application that uses an LDAP server for authentication. However, in case the LDAP server goes down, or something else goes wrong and I still need to access the system, I want to have a master password written directly in the code.
The previous iteration of this system (which I did not write) simply stored the passwords as plaintext (!). So:
if ($username == "dan" && $password == "32fsss") {
which of course is extremely unsecure.
So I want to fix that. I was thinking of hashing the password, so doing
$hashedPassword = password_hash($password);
if ($username == "dan" && $hashedPassword == "HASHPASSWORDSTOREDHERE") {
So I would hard-code the hash for the master password, not the actual password itself. Is this secure? I know a stolen hash is bad, but it's better than a stolen plaintext password.
Of course all user-input would be appropriately sanitized.
Alternatively: any other thoughts for having a master-password access system?
If it's purely a read only incident and all they get is the hashed version, it shouldn't be an issue. That being said, I prefer to use the hash() function rather than password_hash(), but that's just my personal preference.
The only issue is if the attacker who reads the php file and obtains the hashed password has a way to reverse it (i.e. a rainbow table). In this instance, your system becomes insecure. This is where my preference for hash() over password_hash() comes from. With hash(). To generate the hashed form, I can say:
$HashedMasterPassword = hash('md5', $MasterPassword . "MyMD5Salt") . hash('sha256', $MasterPassword . "MyShaSalt");
Then in my uploaded code I can take the output of the above code ($HashedMasterPassword) and hard code that string into my code. This adds two different salts, two different hashing functions and it reduces the already low chance of a rainbow table attack because the attacker would need a collision that occurs for both md5 + the first salt and sha256 + the second salt. This is, I dare say the word, impossible. Sure, pigeon hole effect says it's possible and it is, but this is SO near impossible that I wouldn't fret over it.
That all said, using password_hash() and storing that hash is fine if you really want to. I just personally dislike it.
EDIT: ADDING ON IMPLEMENTATION DETAILS
I believe based on the comments that there was some confusion as to how this would be implemented. Let's say my master password was thisIsMyPassword (Super secret and super secure, I know). Well, we'd need to generate the hard coded hashed form. The hard coded hashed form would be found by saying:
$MasterPassword = "thisIsMyPassword";
$HashedMasterPassword = hash('md5', $MasterPassword . "MyMD5Salt") . hash('sha256', $MasterPassword . "MyShaSalt");
echo $HashedMasterPassword;
Important: You would NOT upload this to the server. This would just be used for generating the hash and it should then be permanently deleted.
The output of this would be: 6dcfc45fba2fff44b7cfc8df7245a1b7804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833
So, in your code that requires a master password to override, you'd enter:
$MasterHash = '6dcfc45fba2fff44b7cfc8df7245a1b7804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833';
$SubmittedMasterPass = $_POST['MasterPassword'];
$HashedVersionOfSubmittedMasterPass = hash('md5', $SubmittedMasterPass . "MyMD5Salt") . hash('sha256', $SubmittedMasterPass . "MyShaSalt");
if($MasterHash !== $HashedVersionOfSubmittedMasterPass){
die('Override Failed. Reason: Wrong Password.');
}else{
// User has successfully logged in using the master password.
}
Again to clarify based on information from the comments, this is more secure than just using SHA256 because a brute-forced master password must be found that produces 6dcfc45fba2fff44b7cfc8df7245a1b7 when MyMD5Salt is appended to the end of it and it also must produce 804c88d63a82ac2ba33e0de32ab7f20c5afe2c1784e87f1bae8a4f91f1a84833 when MyShaSalt is appended onto the end of it. This means the collision must satisfy two different algorithms which is much more difficult to do than satisfying just the Sha256 algorithm on it's own.
However, as noted in the comments, this does take a few more milliseconds to process; so, if decreasing execution time is a big priority to you, then it might be recommended to only use Sha256 on its own rather than using MD5 and Sha256 combined.
If the user has access to the source code. They can just change it, so it doesn't really matter.
One can discuss if such a "backdoor" is desirable or not, but if you cannot decide it for yourself, there are two ways to protect such a hardcoded password. Storing only the hash is surely much better than the plaintext password, because everybody with read-access to the code could otherwise use it on a running system.
The first possibilty is to use a slow hash algorithm with a cost factor, such as password_hash() which you proposed in your example. If an attacker has read-access to the code, he would have to brute-force this password, to use it on a live system. A slow hash algorithm will thwart brute-forcing, while MD5 and other functions are ways too fast (8 Giga MD5 per second). The drawback is a slowdown in your application when the password is verified.
The second possiblity is a very strong password. Choose a long enough random combination, e.g. 70 characters generated with a password-manager and use it as the master key. Even fast algorithms like SHA256 are out of scope for brute-forcing then, and your key is immune against dictionary attacks and does not even need salting.
I know that there are alots of questions about this subject but i really need to ask this.
Today I've been working on encrypting passwords with md5.
So what I've done is.
I got 4 salts. (they changes depending on user values)
from email id and substr then md5 them
from email and id substr other positions
a long string, substr it and then md5 it
another long string, substr it and then md5 it
Then i md5 salt1 and 3 and the password with salt 2 and salt4
After this I have to change the password automatically whenever a user changes his email or his id getting changed.
What do you guys think about this?
Nothing.
MD5 is broken and bad.
Using the mailaddress as salt is a good idea. But using md5 is not. Use instead bcrypt, scrypt or pbkdf2.
Don't invent your own ecryption, unless you really know what you are doing, and trust me, you don't
First, let us define a few terms.
Encryption is when you encode a message so that it cannot be read. Encryption involves a plaintext, a cipher and a key. It is like putting a book (the plaintext) in a locked room (cipher), which can only be opened using a known tool (a key). There are many kinds of encryption, but that is a simple description. Encryption is two-way, meaning that you can encode and decode the message.
Cryptographic hash is when you take any kind of data and generate a fixed size value for it (usually called a hash or a digest). Cryptographic hashes are one-way, which means that you cannot reverse the process.
A salt is a unique string, or a collection of bits, similar to a nonce (a unique number that is only used once). Salts are only used to make it infeasible for a cracker to process a list of hashes. They are not supposed to be used as a secret (i.e. like a cryptographic key). The only reason people usually talk about randomness when it comes to salts is because they want to generate a unique salt (if the randomness is not great enough they may get colliding salts, for instance).
Okay, now to how you should hash a password.
A relatively safe way of hashing a password is to simply tack on a unique hash onto a password, and then save the salt with the password:
$pass = 'this is my password';
$salt = uniqid('', true);
$hash = sha1($pass . $salt);
// INSERT INTO users ('hash', 'salt') VALUES ('$hash', '$salt') WHERE ...
That is an okay way of doing it if your website does not retrieve any sensitive data from its users.
If you deal with sensitive data, or if you just want to make sure that you are doing everything you can to keep stuff safe, then there is a PHP function that does the hashing for you. It is called crypt() (read the documentation to learn how it works). Here is an example of how to hash a password using the function:
$pass = 'this is my password';
$salt = 'unique string';
$hash = crypt($password, '$2y$07$'.$salt.'$');
echo $hash;
That will securely hash a password.
The thing to realize is that the crypt() function is much more secure than anything you can come up with (unless you are a specialist in the area).
In newer versions of PHP (5.5.0+) there is a password hashing API that makes it even simpler to hash a password.
There are also various hashing libraries out there. PHPass is a popular one.
It is bad, because it uses MD5.
MD5 is a very fast operation. It can be executed billion of times per second on graphic cards hardware. It is considered bad practice to use it for any password related things.
Use bcrypt. Use a random salt. Use the upcoming PHP API for hashing, verifying and rehashing passwords. This include file implements it for versions starting with PHP 5.3.7: https://github.com/ircmaxell/password_compat
Well, "MD5 is broken and bad" is a little exagerated. Even if it can be brute-forced with a lot of CPU, it is not "broken" and is still a very useful algorithm for a lot of things involving hashing.
So "MD5 should not be used for password encryption" sounds much better to me.
When using PHP, an easy and safe option is to rely on the password_hash() (which natively generates a random salt) and password_verify() functions.
The advantage is that the encryption algorithm will transparently be updated with each new PHP version (at the moment PASSWORD_DEFAULT is set to bcrypt, but should bcrypt be "broken" it can be set to a newer algorithm), which makes any code using those functions quite resilient.
I personally do not recommend involving of the user id and his email into the hashing of his password.
You can deal with the password by:
Dynamic salt per user based on random string generated on user registration
Prepend one part of the salt and append the other around the password
Double md5: md5(md5($password))
Etc.
a simple way would be to generate a random salt for each user and hash your password like this
public function encodePassword( $raw, $salt ) {
return hash('sha256', $salt.$raw);
}
For high security hash, you can check this link which explain how to implement PBKDF2:
http://crackstation.net/hashing-security.htm#phpsourcecode
I have some doubts about the best way to do a database with passwords. I need encryption in the passwords, but if i use MD5 i can't recover the pass, isn't it?
And the base64 encoder ? it is secure? with this encryption the recover isn't more a problem.
Suggestions? what is the best way? e prefer a solution that permit to remember the old pass, and not define a new one password.
Thanks!!!
If anybody know a good tutorial about secure passwords in a database i really appreciate that
if i use MD5 i can't recover the pass,
isn't it?
Indeed, if you hash your password using md5 or sha1 (adding a salt is a good idea, btw), you will not be able to recover the password ; and that's the goal of doing so !
The idea is if anyone is able to take a look at your database (be it some evil doer, or one of your employees -- who can be an evil-doer), he will not be able to find any usefull password.
what is the best way? e prefer a solution that permit to
remember the old pass, and not define
a new one password.
The best way is to do the opposite of what you want : not allow one to get his old password -- and develop some way of generating a new password.
This way, you will ensure that no-one is able to get a dump of your logins and corresponding password ; which will make your service safer for your users (especially considering that many people use the same login/password couple of several websites).
MD5 is not used for encryption (which implies that it can be decrypted) but rather for message digestion/hashing. Base64 is also not encryption but rather encoding, which can be decoded with no effort.
There is usually little point in storing encrypted passwords in a database if they can be easily decrypted.
The secure approach is to store only hashes and compare submitted passwords to stored hashes after hashing them on the fly.
You should be doing something along the lines of:
$salt = 'some2%string!!here1';
$hash = sha1( $salt . $_POST['password'] );
to create a hash of the password. You store that hash in the database. When a user wants to log in, you take his submitted function, hash it using the same process, and compare to the hash in the database. If they match, the password is correct.
First off, there's a Significant Difference Between Hashing and Encryption. I suggest that you give that a read before going on...
Now, as to your exact question, there are a few ways to go about it.
Encrypt your passwords with a strong cipher so that you can decrypt them when necessary. A solution such as the one in this post may work for that. However, please note that this isn't a great idea, since if your system is ever compromised, all the passwords will be leaked (never a good idea). There are very few use-cases where it makes sense to store them encrypted, but if you absolutely must, please use a strong cryptographic encryption routine to do it...
Store your passwords using a strong one-way hashing method. No, md5($password) is not good enough. But neither is sha1($salt . $password). The first is trivial to lookup most passwords, and the second can be brute-forced in a reasonable amount of time by simple trial and error. Instead, stretch your passwords iteratively. The best way is to use the standard PBKDF2 function to generate a strong one-way key from the password.
As far as how to recover if the user forgets a password, don't worry about it. If the user forgets his password, create a new one and give that one to the user. It's the industry standard way of dealing with forgotten passwords (Heck, both Windows and Mac do it that way). You may think that you're doing your users a favor by sending it to them, but all you're doing is turning off anyone who has a clue about security from every using your application (and making a lot of people mad if you get compromised).
base64 isn't "encryption". It's intended to convert binary data into a format that's safe for transmission through potentially "broken" email systems that can't process 8-bit binary data properly. It's a best the equivalent of a cereal box decoder ring.
If you want encryption, there's AES, DES, and various other functions available. Problem is, if your code can decrypt the password, the it's trivial for an attacker to figure out how you do it, and/or subvert your code to do it for them.
Passwords should never be stored in a format where the plaintext can be retrieved. If a user forgets their password, you wipe out the old one, generate a new temporary one, and force them to change this temporary password to something else on first login.
You should not ever need to remember the user's password - to do so is a violation of their trust and presents a security hole.
Normally you will hash the password with MD5 (these days it's better to use SHA-2), and when the user submits their password to try and log in, hash that password as well, and see if the hashes are a match.
For added security, you can create a "salt" column to the database and generate a random salt when the password is first submitted. Add the salt to the beginning of the password, and then hash it. Store the hash of the salt+password, and the salt together. Now when the user submits his password to log in, you would combine it with the salt, hash it, and check if the hash is a match.
The salt ensures that if multiple users have the same password (chances are they do), their password hashes will not be identical.
If the user forgets their password they will have to provide a new one, simply storing their password and sending it back to them when they forget is bad practice and a sign to the user that you aren't handling their privacy very well.
As mentioned, use a hash instead of encryption when saving passwords. I generally don't use a random salt since this means an extra field in the DB so that you can authenticate the user. The simplest solution is to use the password as the salt as shown below. Easy to use and easy to authenticate.
$salt = $_POST['password'];
$hash = sha1( $salt . $_POST['password'] );
Stop now and read this. Then go find an open source library to do user authentication. I'm not a PHP dev, so I can't refer you to one, but I'm sure they exist. They'll have had the security holes found already.
Also, for passwords, you should be looking at bcrypt or similarly slow hash functions for passwords anyways, instead of using a fast hash algorithm like MD5 or SHA.
I was reading this tutorial for a simple PHP login system.
In the end it recommends that you should encrypt your password using md5().
Though I know this is a beginners' tutorial, and you shouldn't put bank statements behind this login system, this got me thinking about encryption.
So I went ahead and went to (one of the most useful questions this site has for newbies): What should a developer know before building a public web site?
There it says (under security) you should:
Encrypt Hash and salt passwords rather
than storing them plain-text.
It doesn't say much more about it, no references.
So I went ahead and tried it myself:
$pass = "Trufa";
$enc = md5($pass);
echo $enc; #will echo 06cb51ce0a9893ec1d2dce07ba5ba710
And this is what got me thinking, that although I know md5() might not the strongest way to encrypt, anything that always produces the same result can be reverse engineered.
So what is the sense of encrypting something with md5() or any other method?
If a hacker gets to a password encrypted with md5(), he would just use this page!.
So now the actual questions:
How does password encryption work?
I know I have not discovered a huge web vulnerability here! :) I just want to understand the logic behind password encryption.
I'm sure I'm understanding something wrong, and would appreciate if you could help me set my though and other's (I hope) straight.
How would you have to apply password encryption so that it is actually useful?
What about this idea?
As I said, I may/am getting the whole idea wrong, but, would this method add any security in security to a real environment?
$reenc = array(
"h38an",
"n28nu",
"fw08d"
);
$pass = "Trufa";
$enc = chunk_split(md5($pass),5,$reenc[mt_rand(0,count($reenc)-1)]);
echo $enc;
As you see, I randomly added arbitrary strings ($reenc = array()) to my md5() password "making it unique". This of course is just a silly example.
I may be wrong but unless you "seed the encryption yourself" it will always be easily reversible.
The above would be my idea of "password protecting" and encrypted password, If a hacker gets to it he wont be able to decrypt it unless he gets access to the raw .php
I know this might not even make sense, but I can't figure out why this is a bad idea!
I hope I've made myself clear enough, but this is a very long question so, please ask for any clarification needed!
Thanks in advance!!
You should have an encryption like md5 or sha512. You should also have two different salts, a static salt (written by you) and then also a unique salt for that specific password.
Some sample code (e.g. registration.php):
$unique_salt = hash('md5', microtime());
$password = hash('md5', $_POST['password'].'raNdoMStAticSaltHere'.$unique_salt);
Now you have a static salt, which is valid for all your passwords, that is stored in the .php file. Then, at registration execution, you generate a unique hash for that specific password.
This all ends up with: two passwords that are spelled exactly the same, will have two different hashes. The unique hash is stored in the database along with the current id. If someone grab the database, they will have every single unique salt for every specific password. But what they don't have is your static salt, which make things a lot harder for every "hacker" out there.
This is how you check the validity of your password on login.php for example:
$user = //random username;
$querysalt = mysql_query("SELECT salt FROM password WHERE username='$user'");
while($salt = mysql_fetch_array($querysalt)) {
$password = hash('md5',
$_POST['userpassword'].'raNdoMStAticSaltHere'.$salt[salt]);
}
This is what I've used in the past. It's very powerful and secure. Myself prefer the sha512 encryption. It's actually just to put that inside the hash function instead of md5 in my example.
If you wanna be even more secure, you can store the unique salt in a completely different database.
Firstly, "hashing" (using a cryptographic one way function) is not "encrypting". In encryption, you can reverse the process (decryption). In hashing, there is (theoretically) no feasible way of reversing the process.
A hash is some function f such that v cannot be determined from f(v) easily.
The point of using hashing for authentication is that you (or someone seeing the hash value) do not have any feasible way (again, theoretically) of knowing the password. However, you can still verify that the user knows his password. (Basically, the user proves that he knows v such that f(v) is the stored hash).
The weakness of simply hashing (aside from weak hash functions) is that people can compile tables of passwords and their corresponding hash and use them to (effectively) get the inverse of the hash function. Salting prevents this because then a part of the input value to the hash is controlled and so tables have to be compiled for that particular salt.
So practically, you store a salt and a hash value, and authenticate by hashing a combination of the salt and the password and comparing that with your hash value.
MD5 is a one way hashing function which will guard your original password more or less safely.
So, let's say your password is "Trufa", and its hashed version is 06cb51ce0a9893ec1d2dce07ba5ba710.
For example, when you sign in to a new webpage, they ask you for your username and password. When you write "Trufa" as your password, the value 06cb51ce0a9893ec1d2dce07ba5ba710 is stored in the database because it is hashed.
The next time you log in, and you write "Trufa", the hashed value will be compared to the one in the database. If they are the same, you are authenticated! Providing you entered the right username, of course.
If your password wasn't stored in its hashed form in database, some malicious person might run a query somehow on that database and see all real passwords. And that would be compromising.
Also, since MD5 is a 128 bit cryptographic function, there are 2^128-1 = 340282366920938463463374607431768211455 possible combinations.
Since there are more possible strings than this, it is possible that 2 strings will generate the same hash value. This is called a collision. And it makes sure that a hashed password cannot be uniquely reverse engineered.
The only vulnerability with salting is that you need to know what the salt is in order to reconstruct the hash for testing the password. This is gotten around by storing the entry in the authdb in the form <algorithm>$<salt>$<hash>. This way the authdb entry can be used by any code that has access to it.
You're missing the important step - the salt. This is a unique (per user, ideally) bit of extra data that you add to the password before hashing it.
http://en.wikipedia.org/wiki/Salt_%28cryptography%29
Your idea (salting) is well known and is actually well-implemented in the PHP language. If you use the crypt() function it allows you to specify a string to hash, a method to encrypt (in some cases), and a salt. For example,
$x = crypt('insecure_password', $salt);
Returns a hashed and salted password ready for storage. Passwords get cracked the same way that we check if they're right: we check the hash of what the user inputs against the hash of their password in the database. If they match, they're authenticated (AFAIK this is the most common way to do this, if not the only). Insecure passwords (like password) that use dictionary words can be cracked by comparing their hash to hashes of common passwords. Secure passwords cannot be cracked this way, but can still be cracked. Adding a salt to the password makes it much more difficult to crack: since the hacker most likely doesn't know what the salt is, his dictionary attack won't work.
For a decent hash the attacker won't be reversing the hash, they'll be using a rainbow table, which is essentially a brute-force method made useful if everyone uses the same hash function.
The idea of a rainbow table is that since hashing is fast I can hash every possible value you could use as a password, store the result, and have a map of which hash connects to which password. If everyone just takes their passwords and hashes them with MD5 then my hash table is good for any set of password hashes I can get my hands on!
This is where salting comes in. If I take the password the user enters and add some data which is different for every user, then that list of pre-determined hashes is useless since the hash is of both the password and some random data. The data for the salt could be stored right beside the password and even if I get both it doesn't help me get the password back since I still have to essentially brute force the hash separately for every single user - I can't form a single rainbow table to attack all the hashes at once.
Of course, ideally an attacker won't get the list of hashed passwords in the first place, but some employees will have access so it's not possible to secure the password database entirely.
In addition to providing salt (or seed), the md5 is a complex hashing algorithm which uses mathematical rules to produce a result that is specifically not reversable because of the mathematical changes and dataloss in throughput.
http://en.wikipedia.org/wiki/Cryptographic_hash_function
md5 (or better put: hash algorithms in general) are used to safely store passwords in database. The most important thing to know about hashes is: Hashes are not encryptions per se. (they are one-way-encryptions at most). If you encrypt something, you can get the data back with the key you used. A hash generates a fixed-length value from an arbitrary input (like a string), which can be used to see if the same input was used.
Hashes are used to store sensitive, repeatly entered data in a storage device. Doing this, nobody can recreate the original input from the hash data, but you can hash an incoming password and compare it to the value in the database, and see if both are the same, if so, the password was correct.
You already pointed out, that there possibilites to break the algorithm, either by using a database of value/hash pairs or producing collisions (different values resulting in the hash value). You can obscure this a bit by using a salt, thus modifying the algorithm. But if the salt is known, it can be used to break the algorithm again.
I like this question. But I think you've really answered yourself.
The site you referenced uses dictionary lookups of known, unsalted, md5's - it doesn't "crack" anything.
Your example is almost good, except your application needs to be able to regenerate the md5 using the same salt every time.
Your example appears to use one of the random salts, which will fail 2 of 3 times if you try to compare a users password hash to something input.
People will tell you to also use SHA1 or SHA256 to be have a 'stronger' hash - but people will also argue that they're all 'broken.'
That documentation is misleading -- it teaches a "vulnerable" concept and presents it as somehow being "secure" because it (the saved password) looks like gibberish. Just internet junk that won't die. The following link should clear things up (you have already found a good bit of it though, it seems. Good work.)
Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes talks about MD5 (and why it should not be used) along with salt (e.g. how to thwart rainbow attacks) as well as provides useful insights (such as "Use someone else’s password system. Don’t build your own"). It is a fairly good overview.
This is my question about the aspects of md5 collision, slightly related to your question:
Is there any difference between md5 and sha1 in this situation?
The important part is in the first 3 rows, that is: you must put your salt before the password, if you want to achieve stronger protection, not after.
To simply answer the title of your question, md5's only real use nowadays is for hashing large strings (such as files) to produce checksums. These are typically used to see if both strings are identical (in terms of files, checksums are frequently used for security purposes to ensure a file being distributed hasn't been tampered with, for example).
To address each of your inline questions:
How does password encryption work?
How would you have to apply password encryption so that it is actually useful?
Secure password hashing works by taking the password in plain text form, and then applying a costly hashing function to it, salted with a cryptographically secure random salt to it. See the Secure hash and salt for PHP passwords question for more detail on this.
What about this idea?
Password hashing does not need to be complicated like that, and nor should it be. Avoid thinking up your own algorithms and stick with the tried and tested hashing algorithms already out there. As the question linked above mentions, md5() for password hashing has been obsolete for many years now, and so it should be avoided.
Your method of generating a "random" salt from an array of three different salts is not the randomness you're looking for. You need unique randomness that is suitable for cryptographically secure (i.e. using a cryptically secure pseudo-random number generator (CSPRNG)). If you're using PHP 7 and above, then the random_bytes function can be used to generate a cryptographically secure salt (for PHP 5 users, the random_compat library can be used).
I am connecting to a MySQL database with PHP and the CodeIgniter Framework. I want to store my passwords encrypted in the database and would like to know the best way to do this.
From a high level overview - don't encrypt, hash. And if you can, use BCrypt. Here's a long article explaining why BCrypt and why hashing.
Encrypting the passwords is a bad idea. If somebody gets your database, they're probably going to get the key you used to encrypt the passwords as well.
The real solution is to hash, salt, and then store the passwords. Jeff Atwood has an awesome post on this:
http://www.codinghorror.com/blog/archives/000953.html
And here is one discussing "rainbow tables," massive tables of words with their MD5 sums:
http://www.codinghorror.com/blog/archives/000949.html
The best way, in that it is both easy and secure, is to use phpass. If your PHP installation does Blowfish, it uses bcrypt; if it doesn't, it uses multiple passes of md5. Either way, it's more secure than straight md5 or sha1.
$hasher = new PasswordHash(8, false);
// Before storing a password
$hash = $hasher->HashPassword($password);
// To check a password against a hash
if ($hasher->CheckPassword($password, $hash))
// $password and $hash match
I always md5sum passwords before I put them into the database, and then also md5sum password login attempts to check them against the db. Just for safety, I do a select query using a where clause with userID (username) AND md5summed password so that I don't get any rows back at all unless both match.
Also, mysql interanlly uses md5summing on it's passwords if you need a level of trust in this method of password obfuscation.
Use a hashing function; MD5 will do fine. Don't store the password, store the hash. Then, to log users in, hash the password they entered and compare it to the hash in the database; if the hashes match, they're legit.
Also, add a salt to the password before you hash it. This can be easy as just appending a string to the password, like your domain name or some other data that's unique to your app. This prevents hackers from using rainbow tables against your hashes.
Never store passwords. Use a one way hash and store that.
hmm, I hash, more than once based on whatever math springs to mind at the time of writing the storing and validation of passwords
From here on I'll probably go with OpenID as much as possible wherever I have an actual choice tho, so i don't have to do any password storage at all. That way I can leave passwords up to the experts, and the users already trusted party.
I agree with hashing and salting. I disagree with picking a site-wide hash. Use a different salt for each user to prevent dictionary attacks against all your passwords at once.