Where possible, don’t write code to handle passwords. In particular, if the application is local, try to depend on the normal login authentication by a user. If the application is a CGI script, try to depend on the web server to provide the protection as much as possible - but see below about handling authentication in a web server. If the application is over a network, avoid sending the password as cleartext (where possible) since it can be easily captured by network sniffers and reused later. “Encrypting” a password using some key fixed in the algorithm or using some sort of shrouding algorithm is essentially the same as sending the password as cleartext.
When transmitting passwords over a network, cryptographically authenticate and encrypt the connection. (Below we will discuss web authentication, which typically uses SSL/TLS to do this.)
When implementing a system that users log in to using passwords (such as many server), never store the passwords as-is (i.e., never store passwords “in the clear”). A common problem today is that attackers may be able to briefly break into systems, or acquire data backups; in such cases they can then forge every user account, at least on that system and typically on many others.
Today, the bare-minimum acceptable method for systems that many users log into using passwords to use a cryptographic hash that includes per-user salt and uses an intentionally-slow hash function designed for the purpose. For brevity, these are known as “salted hashes” (though many would use the term “salted hash” if it only met the first two criteria). Let's briefly examine what that means, and why each part is necessary:
Cryptographic hash: A cryptographic hash function, such as SHA-512, converts data into a “fingerprint” that is very difficult to invert. If a hash function is used, an attacker cannot just see what the password is, but instead, must somehow determine the password given the fingerprint.
Per-user salt: An attacker could counteract simple cryptographic hashes by simply pre-hashing many common passwords and then seeing if any of the many passwords match one the precomputed hash values. This can be counteracted by creating, for each user, an additional random value called a salt that is used as part of the data to be hashed. This data needs to be stored (unencrypted) for each user. Salt should be generated using a cryptographic pseudo-random number generator, and a it should have at least 128 bits (per NIST SP 800-132).
Key derivation / iterated functions: The stored value should be created using a key derivation or key stretching function; such functions are intentionally slightly slow by iterating some operation many times. This slowness is designed to be irrelevant in normal operation, but the additional cycles greatly impede attackers who are trying to do password-guessing on a specific higher-value user account. A key derivation function repeatedly uses a cryptographic hash, a cipher, or HMAC methods. A really common key derivation function is PBKDF2 (Password-Based Key Derivation Function 2); this is RSA Laboratories' Public-Key Cryptography Standards (PKCS) #5 v2.0, RFC 2898, and in "Recommendation for Password-Based Key Derivation" NIST Special Publication 800-132. However, PBKDF2 can be implemented rather quickly in GPUs and specialized hardware, and GPUs in particular are widely available. Today you should prefer iteration algorithms like bcrypt, which is designed to better counter attackers using GPUs and specialized hardware.
If your application permits users to set their passwords, check the passwords and permit only “good” passwords (e.g., not in a dictionary, having certain minimal length, etc.). You may want to look at information such as http://consult.cern.ch/writeup/security/security_3.html on how to choose a good password. You should use PAM if you can, because it supports pluggable password checkers.