I am working on a script and need to save passwords. For development purposes, I have been using the crypt() function because it was easy and available. Now that I am mostly done, I want to replace it with something a little better and more consistent.
Some of the concerns I have are:
not all algorithms are supported on every system
sometimes the salt is pre-pended to the result (seems like a security problem)
I want something that works with PHP 4.3+.
Is there anything available, or should I stick with crypt()? I thought about using md5(md5($password).$salt). Thanks for the insight.
There is nothing wrong with crypt
If your server does not support it, use another server.
You should NEVER use MD5 for hashing passwords (or even SHA1 for that matter)
Use either bcrypt (the blowfish method of crypt) or pbkdf2
There is an implementation of pbkdf2 here:
Encrypting Passwords with PHP for Storage Using the RSA PBKDF2 Standard
More information on why and how here:
Which password hashing method should I use?
Do any security experts recommend bcrypt for password storage?
First of all: Prepending the salt is not a security problem. Having a per-password salt is a big goodie, and it's perfectly OK to it being store alongside the pw.
Now: As long as you don't transport password hashes from one system to another, and the latter not supporting the default algorithm of the first, nothing bad will happen by definition. Since PHP 5.3 there are built-in algorithms in PHP such as Blowfish, that are guaranteed to be available.
Related
I have a super old version of php (please don't tell me to upgrade for it will never be an option in our case) and i need to store passwords. I had seen posts like this and many more that says, use crypt() of php. I am just confuse with one thing:
My question is which is proper way of storing password; Use ONE SAME SALT for all passwords of different users or DIFFERENT RANDOMLY GENERATED SALT for each password of users?
My question arise because in my experience, i haven't seen a database/table with salt in each row, some have a one salt in a config file and it is being used for salting all of the passwords. Also, i think storing different salt in each user simply means more bytes to store.
Thanks guys ♥
You want to use a different salt. The idea being is that a salt will impact the resulting hash.
When "hacking" passwords that have been exposed, malicious people will use "rainbow tables". These are essentially a reverse look up that finds strings that hash to the given value. Rainbow tables can also be generated for common passwords.
If you use one salt, a hacker will only have to generate one rainbow table. If you use a new salt for each password, the hacker has to generate rainbow tables for each password they wish to compromise.
It is relevant to upgrade your PHP for modern hashing librarys (like bcrypt). However, there are back-ports for older versions of PHP which I seriously recommend. Hashing functions for passwords are designed to be computationally expensive so that a password takes time to verify. The idea being that you cannot verify 1000 different password possibilities in any reasonably short amount of time.
Create a unique salt for each password, this is the only safe method. How you can calculate the hash, depends on how old your PHP version actually is:
Version 5.5 of PHP will have built-in support for BCrypt, the functions password_hash() and password_verify(). This function will generate a safe salt on its own and includes it in the resulting hash-value.
For PHP version 5.3.7 and later, there exists a compatibility pack, from the same author that made the password_hash() function. You can then already use the password_hash() function, and should you switch to a newer PHP version you do not have to change your code.
For PHP versions before 5.3.7 there is no support for crypt() with 2y, the unicode safe BCrypt algorithm. One could use the compatibility pack and replace it instead with 2a, which is the best alternative for earlier PHP versions.
For PHP versions before 5.3, there is no support for BCrypt at all. Your best bet will probably be the phpass framework then.
Note that the crypt() function will not create a safe salt on its own, though it will include it in the resulting hash-value. For verification it will extract it from there.
Using a single salt for every hash will always prevent a rainbow table attack unless a specially generated rainbow table is generated using the salt you were using, which is astronomically impossible unless your salt is a single character or was known beforehand.
Using the same salt for every hash is also great against hackers that have access to your SQL database but not your back-end code.
However if a hacker has access to your static salt it makes having it almost useless against the speed of a brute-force attack, which having a salt for every user would mitigate.
You should use both a hard-coded static salt and a dynamic salt to both prevent a rainbow table attack and mitigate a brute-force attack.
I want to create a membership site so i want to make the passwords as safe as possible. I can see from reading sites including this one the md5, sh1 encryption are a serious no no. I've seen some other things like bcript, scrypt, sha256, sha512 and PBKDF2. I have found some php scripts implementing these but not really found anything of note to do with the database.
Do i have to create a row containing the salt?
Verifying the password do i have to do something like hash(salt+password) = $hash?
Because i'm not the most experienced at passwords i'm not really sure of the best practices, how when you hash the password + salt what happens then, how the passwords are retrieved...
I think because i dont really understand the logic behind it i'm feeling a little confused about how to go about it.
If you use Bcrypt, Scrypt, or PBKDF2, the salt is part of the hash you get, so no, you don't have to worry about storing it separately. Otherwise (SHA-*), yes — but you shouldn't use those anyways. Bcrypt, Scrypt, and PBKDF2 are actual password-hashing functions.
I'd recommend Bcrypt, since you tagged this php. It's built-in. Scrypt isn't.
A common best practise (see e.g. Linux passwd) is to store the password hashes as
$<algorithm>$<salt>$<hash>
for example this string:
$6$Lxgyf7h6DtkrqwT$0w/BoB6neYjEtdQdUEs3ftnnNguBNTug8.g/9UeMmZ9bN/cDJCE0dj8.4D/8HPN5bMqFPJ4ECnGl5M2iqBmmv/
is a salted SHA-512 (algorithm id 6) password hash salted with Lxgyf7h6DtkrqwT that should be understood by most servers out of the box.
The benefit of this is that you can actually support different algorithms at the same time. So some users may still have e.g. SHA-256 passwords, while for any user changing his password you switch to a more secure algorithm.
A good starting point to read about modular hashing schemes, read this article in Wikipedia on the crypt (Unix) function. The hype around bcrypt (and the misinformation that crypt would equal DES hashing) is indicative of a certain naiveness of PHP developers with respect to password security. bcrypt is not bad (well, it relies on computational complexity instead of stronger algorithms AFAIK, but it certainly seems to beat MD5). But I would advise using something like this scheme which is A) portable, and B) extensible, so that you can at any time smoothly transition to stronger password hashes.
In 99% of programming languages (including PHP), this functionality is available out of the box via the crypt function, by choosing an appropriate salt, starting with $6$ and the appropriate length of salt characters.
And to clean up some of the misinformation systematically spread by bcrypt advocates: this is not using just one round of sha-512, but the default apparently (see http://www.akkadia.org/drepper/sha-crypt.html ) is 5000 rounds of SHA-512. And you can choose to increase the number. So for my understanding the "but bcrypt can be scaled up when needed" claim also holds for crypt-SHA512. In contrast to bcrypt, this should be available on any Linux system using glibc 2.7 onward. bcrypt is an extension only available on some distributions or with some extensions. On Debian and probably Ubuntu you apparently need to install the extension
libpam-unix2 - Blowfish-capable PAM module
I was looking about best practice for password protect, everybody are talking about bcrypt and others hashing classes. But I can't get how To verify password if it contains unique random salt .
For cookies its fine, but without em - each time would be unique crypted value, how can I verify users password with random values? Oo . Or bcrypt only for cookies?
Then what I should do with password in db?
Please describe to me my mistakes - what I've lost when learning about it.
The bcrypt algorithm creates a random salt that is stored as part of the hash in a standardised way.
See How do you use bcrypt for hashing passwords in PHP? for a working example.
See also:
Secure hash and salt for PHP passwords
(edited heavily since my answer was wrong before)
There will be a group of function in the next php version, for details see the accepted RFC.
Anthony, the author of the RFC and the patch was kind enough to provide a compatibility library written in php so you can start using this new functionality now!
Behind the scenes it uses crypt with the strongest algorythm currently known.
I know that there are more than a dozen questions about this. But I want to know if it would be better to encrypt passwords for a login system with hash methods like sha1, sha512 etc or would it be better to use Mcrypt ciphers for this ?
I know that decrypting after encrypting with hash methods like sha it's impossible, and if encrypting using mcrypt it's possible. But is it safe to use mcrypt since you can also decrypt ?
Passwords must not be recoverable. The point of hashing them is to make sure that if the database is compromised, the attacker can't get access to every password and thus every user's account (and every account on other services where the password has been reused).
For a password storage that you don't need the plaintext passwords lateron you always should use a Hash-Function. That way you can check the passwords, but a potential attacker cannot find out the plain-text passwords (This is relevant when users always use the same password)
Passwords must NOT be recoverable. As such, you need to use hash algorithms. The most popular are MD5 and SHA1. I won't suggest using MD5 because it can be easily attacked and there are many pregenerated hashes. SHA1 is better, but it has some, too. The most secure is SHA256/SHA512 (part of SHA2 family) based on this. Although, the problem with the SHA2 family is that it is very much based on SHA1. It is not yet broken, but it can be broken soon. If you have time, you may port one of the algorithms made for the SHA3 competition or a less known algorithm. If you can install extensions, then the SHA3 competitors already have PHP extensions.
A good table for the security level is at the Wikipedia. And if you have chosen, you should google "collision attack on [algorithm]" and [preimage attack on [algorithm]" to see whether is there an attack (Wikipedia might be outdated).
Also, don't forget to salt. That means that you hash the $string+"Whatever" instead of $string.
I'm rewriting my password hashing function.
It currently uses sha1.
I'm thinking about using sha512.
Am I right to think that sha512 is sha2?
Is this currently the standard for hashing passwords or should I use another hashing algo?
I would suggest using bcrypt to hash passwords.
This site gives some good background on the issue: http://codahale.com/how-to-safely-store-a-password/
SHA-2 uses four different bit sizes:
hash functions with digests that are 224, 256, 384 or 512 bits.
It should suffice to say whether bcrypt or SHA-512 is good enough. And the answer is yes, either algorithm is secure enough that a breach will occur through an implementation flaw, not cryptanalysis.
If you insist on knowing which is "better", SHA-512 has had in-depth by NIST and others. It's good, but flaws have been recognized that, while not exploitable now, have led to the the SHA-3 competition for new hash algorithms. Also, keep in mind that the study of hash algorithms is "newer" than that of ciphers, and cryptographers are still learning about them.
Even though bcrypt as a whole hasn't had as much scrutiny as Blowfish itself, I believe that being based on a cipher with a well-understood structure gives it some inherent security that hash-based authentication lacks.
So, my recommendation of bcrypt stems from the assumptions 1) that SHA-2 family of hash functions has better scrutiny, and 2) that cryptanalytic methods for ciphers are better developed than those for hash functions.