Why is PHP's hashing Algo not working right? - php

I use PHP's PASSWORD_DEFAULT as the hashing Algorithm; now, I noticed that, if I use it with a salt, only the first 8 chars are verified.
Here is a bit of code I wrote to test that:
<?php
$test_pw = "%ImAVery1234Secure!Password$";
$test_pw_to_be_hashed = "%ImAVery";
//
$salt = bin2hex(openssl_random_pseudo_bytes(32));
$password = $salt.$test_pw;
$password_hashed = password_hash($salt.$test_pw_to_be_hashed, PASSWORD_DEFAULT);
echo password_verify($password, $password_hashed);
?>
This returns 1 for me. If I remove one more chars from the test_pw_to_be_hashed value, it returns 0.
Is there any way to hash the whole password? Do I have to use another hashing algorithm?
If I have to use another hashing algorithm, is there any way to check it with PHP's password_verify method, or do I have to "re-hash" it and then just check both values like below?
if(password_hash($salt.$test_pw_to_be_hashed, OTHER_ALGO) == $db_password)
If I have to change the hashing algorithm, is there any way to re-hash the passwords used currently, or do I have to hash them again when I have the plain text password (when a user logs in again)?

The built-in function password_hash already generates a random hash for you. It returns a string containing the algorithm identifier, the salt and the cryptographic hash. This complete string is confusingly called "hash" itself in the PHP docs. In fact it is a composition containing the hash.
The function password_verify can identify the hash algorithm, the salt and the hash from the string generated by password_hash.
$hash_from_db = '$2y$10$1Ow3T9597X1e9W8dtVbKK.VAAo6Op6xIbglp.3amRCSVgLlTevhjS';
$test_pw = '%ImAVery1234Secure!Password$';
// this gives another hash each time due to a random salt
echo password_hash($test_pw, PASSWORD_DEFAULT), PHP_EOL;
// this verifies against a strored hash
echo password_verify($test_pw, $hash_from_db) ? 'correct' : 'incorrect';
A cryptographic oneway hash function is meant to be irreversible by design. Thus there is no way to rehash older hashes directly. You have to wait until the next login. Then you can check whether the hash in the database is compliant to the current security standard. Older algorithms will still work. First check as usual, whether the provided password is correct. Then recreate a new hash from the given plain password.
If you for some reason do want an additional own long salt string, you have to store that along with the hash as well. When verifying, you need to use that same salt with the user provided password in the same way as you have built the hash input before and pass the combined string to the password argument of the password_verify function.
Since some crypto algorithm might limit the length of the password input, it is a good idea to append further salt strings to the end of the password rather than prepending. Otherwise in the worst case the verification would always be true when the input is truncated to a shorter length than the length of a prepended salt.
As stated in the password_hash PHP docs
Caution
Using the PASSWORD_BCRYPT as the algorithm, will result in the password parameter being truncated to a maximum length of 72 bytes.
bcrypt is the current default algorithm used by password_hash. Thus prepending instead of appending a longer salt would counteract the security.
Though building a longer hash from the generated hash by an own implementation would be possible, cryptography is a complex sciency and custom implementations will most likely introduce more security holes (e.g. timing attacks) rather than increasing security. Use the options provided by PHP's implementations instead, e.g. adjust the cost of the calculation as documented in Predefined Constants. A calculation time of about 3-6 seconds is a fair compromise. This is usually done only once per session and the session is secured by a less secure session id. Consider to reask the password when accessing sensitive data like password change, critical personal information aso.
Keep in mind that even a strong password hash algorithm is considered as not secure enough. Consider to implement multi factor authentication, e.g. sending a TAN to a mail address or mobile phone or even better supporting a cryptographic hardware dongle. (This does not replace but extend password security!)

Related

I'm not understanding the password_hash() function

I've just learned that PHP has a password_hash() function, instead of manually calling a hashing algorithm on a password.
http://php.net/manual/en/function.password-hash.php
But I have two questions about the documentation.
The first one is about the default hashing algorithm, using PASSWORD_DEFAULT as the algorithm. Since PHP 5.5 the algorithm is bcrypt, and then it says:
Note that this constant is designed to change over time as new and
stronger algorithms are added to PHP. For that reason, the length of
the result from using this identifier can change over time. Therefore,
it is recommended to store the result in a database column that can
expand beyond 60 characters (255 characters would be a good choice)
How am I supposed to still keep users being able to log in after a hashing algorithm changes, if I'm only keeping the result of a hash, and the result of the password hash will become different?
Under the salt option it says:
Warning The salt option has been deprecated as of PHP 7.0.0. It is now
preferred to simply use the salt that is generated by default.
If the function will generate a salt, then wouldn't the resulting hash be different in two different executions for the same password? Unless the algorithm for generating salts is such that the same password would always get the same salt, but that would defeat the purpose of using salt, wouldn't it?
How am I supposed to still keep users being able to log in after a hashing algorithm changes, if I'm only keeping the result of a hash, and the result of the password hash will become different?
If the function will generate a salt, then wouldn't the resulting hash be different in two different executions for the same password?
The password_verify() function will detect the hash (and salt) used to hash a specific password and act accordingly.
Use that function to check whether the password input by a user is correct.
How am I supposed to still keep users being able to log in after a hashing algorithm changes, if I'm only keeping the result of a hash, and the result of the password hash will become different?
The password_hash documentation currently gives the following example:
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
This produces output that looks like
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
When you call password_verify, you call it like
password_verify('rasmuslerdorf', '$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a')
Note that this does not have parameters for the algorithm or options. Why? Because they are stored in that output.
Algorithm
2y
Cost
10
Salt
.vGA1O9wmRjrwAVXD98HNO
Actual hash
gsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
In other words, password_verify does not get the algorithm from what your program is currently using. It gets it from what is stored in the database. So even if you change the algorithm, it will still use the old algorithm to verify the hash. The actual recommended way to do password verification is something like
if (password_verify($password, $hash)) {
if (password_needs_rehash($hash, $algo, $options)) {
$user->set_hash(password_hash($password, $algo, $options));
}
return true;
}
return false;
This will update the hash at login whenever it is out of date. The $user->set_hash method would save the new hash to the database (you have to implement this; the password_ functions are part of PHP). The $password is the plain text version just entered by the user. The $hash is the hash previously stored.
You can read more about this at password_needs_rehash in the PHP documentation.
If the function will generate a salt, then wouldn't the resulting hash be different in two different executions for the same password?
It would, but you don't call password_hash to verify the password. Instead, you call password_verify. The password_verify function does not generate a salt. It uses the one from the hash.
You might then ask why use a salt? This is covered extensively in other questions' answers (e.g. here), but the short version is to prevent rainbow tables. With a salt, you would have to create one rainbow table per salt. In this example, the salt is twenty-two characters long. Even if we limited salts to just decimal digits, that would be 10,000,000,000,000,000,000,000 tables. If we allow salts to be any base 64 digit, it's much bigger. Salts don't need to be secret to prevent rainbow tables.

Does Bcrypt require anything to make it secure

I've been looking at encryption methods for a while now and what I've found so far is that Bcrypt is one of the best ways to do so right now. What I don't get yet is the way that Bcrypt works precisely. I understand that it takes longer to solve which is why it makes bruteforcing so hard.
But I don't understand whether it requires other measures such as a random salt to make it secure. Especially after reading about md5 and how having a random salt is almost mandatory before a hash becomes secure.
The sample code I found on php.com is this:
$options = [ 'cost' => 12, ];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>
I'm guessing the cost simply makes it so it runs through the function 12 times to encrypt the word "rasmuslerdorf". And the "PASSWORD_BCRYPT" selects the Blowfish algorithm.
Are there any big differences between PASSWORD_DEFAULT and PASSWORD_BCRYPT?
Is it enough for me to use the default function to encrypt the password on registration. And than compare the password after encrypting it that the user enters on login to the encrypted password in the database?
I'm guessing the cost simply makes it so it runs through the function 12 times to encrypt the word "rasmuslerdorf"
No, the cost parameter effects an exponential amount of work to be done.
But I don't understand whether it requires other measures such as a random salt to make it secure.
The password_hash() function automatically generates a random salt whenever you run it; alternatively, a custom salt can be passed via the options:
password_hash('bla', PASSWORD_BCRYPT, ['salt' => ...]);
By passing a custom salt you're assumed to know what you're doing. For all practical purposes you should be safe to stick with automatically generated salts.
Are there any big differences between PASSWORD_DEFAULT and PASSWORD_BCRYPT?
The PASSWORD_DEFAULT algorithm is provided to future-proof your code by always using the strongest algorithm available at that time (provided you update PHP). The notable difference is in storage requirements; whereas Bcrypt always uses 60 characters, you need to cater for bigger storage (e.g. 255 characters) for whatever will be used in the future.
And than compare the password after encrypting it that the user enters on login to the encrypted password in the database?
Please look at password_verify() for examples on how to verify the password a user enters.
The Bcrypt algorithm is the default algorithm. So, PASSWORD_DEFAULT and PASSWORD_BCRYPT are the same. The default algorithm can be configured in your php.ini file, but if you did not know that then it is most likely still the default.
The cost number is not how many times it is hashed. How many times it is hashed is calculated by using the formula, 2^cost. So, if the cost is 12 then it will be hashed 2^12 times (4096).
You do not have to think about salts when using the function. It creates the salt itself and appends it to the output hash:
$[algorithm]$[cost]$[salt 22 chars][rest is the hash]
You should never touch the hash, when using the password hashing functions. To verify a password against the has you should use password_verify().
The function you are using was made so that people can hash passwords without knowing what is happening in the background. That is a good thing, because when it comes to hashing passwords it is very easy to get it wrong, even if you think you know what you are doing.

Md5 salt password php

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

openssl_digest vs hash vs hash_hmac? Difference between SALT & HMAC?

I want to use SHA512 to store passwords. To do that, which of openssl_digest, hash and hash_hmac should I use and why?
What is the difference between SALT & HMAC?
I just read that HMAC is built on top of hash function.
So is SHA512+SALT+HMAC really necessary or SHA512+SALT or SHA512+HMAC?
So, first off, let's clear one thing up. openssl_digest() === hash(). It's just another function by a different name that does the exact same thing. It computes a cryptographic hash of the input.
So, now we have the question: When storing passwords, which is better: hash or hash_hmac?
Short Answer:
Neither
Long Answer:
As it turns out, The Rainbow Table Is Dead. Just using hash($password . $salt) or even hash_hmac($password, $salt) is not good enough for password storage. Period. If you're doing so, stop right now.
The reason is simple: computation time on a computer (or GPU) is incredibly cheap. It's so cheap, that to brute force a list of passwords is cheap enough that you need to worry about it. Remember, hash functions are designed to be fast. Not expensive...
But, as it also turns out, there is a way to make those fast hash functions more expensive. In fact, it's pretty simple: iterate.
Now, I know what you're thinking. You're going to just loop over the hash:
function hash_password($password, $salt) {
$hash = hash("sha512", $password . $salt);
for ($i = 0; $i < 1000; $i++) {
$hash = hash("sha512", $hash);
}
}
Surely that's good enough, right? Nope. As explained in Fundamental Difference Between Hashing and Encryption, that's not a good idea. So why not just feed back the password and salt in again?
function hash_password($password, $salt) {
$hash = hash("md5", $salt . $password);
for ($i = 0; $i < 1000; $i++) {
$hash = hash("md5", $hash . $password);
}
}
In fact, this is exactly what PHPASS uses (slightly tweaked, but this is the base algorithm)...
So now 1 call to hash_password executes 1000 hash cycles.
But can we improve on that?
Well, as it turns out, we can. The next logical thing to do would be to see if we can get more hash cycles for the same amount of time. And this is where hash_hmac() comes in. As it turns out, HMAC uses 2 hash cycles each time it's called. And because it's all C, it only takes about 1.5 times the amount of time that hash() takes to do a single round.
So that means if we replace hash with hash_hmac, we can instantly see a 33% increase in the amount of work being done in a specified time. So now we're here:
function hash_password($password, $salt) {
$hash = hash_hmac("md5", $salt, $password);
for ($i = 0; $i < 1000; $i++) {
$hash = hash_hmac("md5", $hash, $password);
}
}
And this is actually the basic inner-loop of PBKDF2.
But can we get better?
Yes, again, we can get better. If we look closely, we can see that -in addition to password and salt- all of the above algorithms use a very small amount of memory. In the case of sha512, they'll use on the order of 128 to 256 bytes (buffers and state) to hash the password. Since the memory use is so small, it's trivial to run a lot of them at once side-by-side in a GPU. If we could only increase the memory usage...
Well, as it turns out, we can simply use bcrypt, which is an adaptive hashing algorithm. It has an advantage that it uses more memory than the above algorithms (on the order of 4 to 5kb). So it's more resistent to parallelizing. And it's resistent to brute forcing since it's computationally expensive.
Luckily, it's available for PHP:
crypt($password, '$2y$07$usesomesillystringforsalt$')
Note that crypt() uses many algorithms, but the $2y$ and $2a$ algorithms are bcrypt.
But can we improve on this?
Kind-of. There is a relatively new algorithm called scrypt. It's better than bcrypt, because it's just as computationally expensive, but uses a LOT more memory (on the order of 20mb to 40mb to hash a single password). Therefore, it's even more resistent to parallelization...
Unfortunately, scrypt is not available in PHP yet (I'm working on changing that). Until then, use bcrypt...
Sidenote
After the recent lessons from LinkedIn, LastFM, Hotmail, Gawker, etc, the proof is apparent that a lot of people are doing it wrong. Don't do it wrong, use a library with a vetted algorithm. Use CRYPT_BLOWFISH (bcrypt), use PHPASS, use PasswordLib. But don't invent your own just because you don't want to pull a dependency... That's just negligence.
More reading:
Properly Salting Passwords - The Case Against Pepper
GPU Accelerated PBKDF2
Many Hash Iterations, Append Salt Every Time?
MD5 Decoding, How Do They Do It
HMAC is a specific way to use a hash algorithm (like SHA512). It's used to sign a message and you can then verify that the message is from a specific signer and has not been altered. So this isn't what you want.
A salt is used to add a bit of "randomness" to a text that should be encrypted or hashed. The point is that even if you encrypt the same text several times you'd get different results. This makes it harder to do some attacks. This is what you want: SHA512(salt+password).
For storing passwords, the most secure way I could imagine would be:
(disclaimer: I'm not very experienced with cryptography and there might be a better solution)
Client (JavaScript code?) would generate a salt value.
The client then combines salt and password, and run the result through your hashing algorithm.
The client then transmits both salt and hash value to the server which stores it (preferably in different locations).
To verify a password, you'd then do:
Pass the salt to the client.
Client combines salt and entered password, runs it through your hashing algorithm.
Client sends the hash value to the server.
Server compares the hash value with the stored hash value. If they match, it was the same password.
Of course you could transmit the password in plaintext and do the whole salting and hashing on the server, but this would weaken your solution dramatically. You should never transmit the password in plaintext.
But the "pass the salt to the client" part might be a problem. One way that I could imagine to solve this would be to somehow derive the salt from the username (easiest way: simply do lowercase(username) + password), but the problem with that would be that the salt would be predictable and thus weakening your solution a little bit. Yet, it's still way better than transmitting the "raw" hash and you wouldn't even need to store the salt as you could derive it from the username every time. Should your password DB get stolen it would still resist a rainbow table attack with this "salting with username" approach.
The problem is that a man-in-the-middle attack is still possible. If an attacker would intercept username and hash it has all the relevant infos and it wouldn't be any different than transmitting the plaintext password. So you might want to secure the connection with SSL (HTTPS).
According to IT Security experts:
Use Bcrypt Source: https://security.stackexchange.com/a/10905/7599.
I would give answer according to SO point of view.
openssl_digest vs hash vs hash_hmac
openssl_digest - Computes a digest.
hash Generate a hash value (message digest)
hash_hmac — Generate a keyed hash value using the HMAC method
And In cryptography, a hash-based message authentication code (HMAC) is a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret key.
As said by ircmaxell, hash or hash_hmac are not better for storing passwords with SHA-512. I would rather say, you can use openssl_digest for storing passwords.
See SHA-512 library for PHP
SALT vs HMAC
A hash, in this context, is a one-way function - i.e. a function that makes it very easy to find the result from the argument (the password) but difficult (or impossible) to find any argument that generates a given result.
A salt is some auxiliary data that augments the argument to a hash function. This is useful as it prevents accidental discovery of passwords through observation that two hashed passwords have identical values. With a salt, the stored/transmitted value will only be identical if both the salt and the password match.
An HMAC refers to the application of a hash (and optional salt) to a "message authentication code" - which, depending upon context might be a password... or, at least, there's nothing stopping you passing a password into the HMAC as if it were the message authentication code.
HMAC is meant to be used in cases where you have a random and secret
key. For these cases, HMAC is usually better than other ways of
incorporating the key into the hash function. (For example, using HMAC
takes care of things like extension attacks, etc.)
Salt is usually a random value that is not secret. That is to say, when
you use the term salt you usually refer to situations where there is a
random value that may very well be known to the attacker. The security
of the system should therefore not depend on the salt being kept
secret. In these situations HMAC is often not a very good choice.
HMAC and Salt comparison is not logical. Personally I'd use a salt and a hash function... and I wouldn't be paranoid about the strength of the hash function as its unlikely to be the weak link in any practical system....
See http://www.derkeiler.com/Newsgroups/sci.crypt/2006-01/msg00321.html

Using crypt(), how does my app validate passwords that have randomly generated salts?

I've been looking at PHP's crypt function and a few questions on Stackoverflow, and I'm trying to figure out salted and hashed passwords.
I found this on the PHP community page:
<?php
function md5crypt($password){
// create a salt that ensures crypt creates an md5 hash
$base64_alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
.'abcdefghijklmnopqrstuvwxyz0123456789+/';
$salt='$1$';
for($i=0; $i<9; $i++){
$salt.=$base64_alphabet[rand(0,63)];
}
// return the crypt md5 password
return crypt($password,$salt.'$');
}
?>
How does something like that compare to:
<?php
// Slightly modified example from PHP community page
$password = trim(mysql_prep($_POST['password']));
// Get the hash, letting the salt be automatically generated
$hashed_password = crypt($password);
?>
Here's an excerpt from another question:
However, the PHP crypt() function can
use a variety of different hashes to
compute the hash. When you prefix your
salt with "$1$" you get a hash with an
MD5. When you prefix with $2$ you get
a crypt with blowfish, which is more
secure.
The "$1$" is prefixed to the output so
that the hash can be verified. If it
wasn't included, there would be no way
to know from the stored hash which
algorithm should be used! This
information would have to be stored
elsewhere. To save you this trouble
PHP includes the algorithm in the hash
output.
My head is spinning a bit concerning hashes, encryption and salts... but the part that really stumps me, is how do I compare a user-entered password against a salted hashed password, if the salt is randomly generated upon user creation... and not stored--and on top of that, what's the point of using crypt() with an automated salt, if you HAVE to specify the correct prefix to be able to validate the password again upon user return?
You need to store the salt with the user.
The purpose of the salt is to ensure that two users with the same password get different hashes.
This prevents rainbow table attacks.
EDIT: Your salt should contain (cryptographically-secure-)random bytes.
Right now, you're restricting it to only contain letters and numbers
The idea is to have a random salt for every user/password.
Adding a salt will just make more difficult to guess your password, but using a random salt for every account will increase the security as it'll reduce the way for an attacker to guess any other passwords, as given some current and unsecure password and/or username, the reverse engineering to guess password would be easy.
It has a big impact on cross-system security as people tends to use the name username/password on most sites.
Using a random salt makes an attack almost impossible with a dictionary as you'll need to compute every salt possible to guess any password.
If you look closely at the format of /etc/shadow, you'll see the nomenclature in the second field (with : delimiting fields):
username:${enctype}${salt}$HoPeFuLlYVerYloNGpassWOrDhAsh: ... ... ...
The salt is actually stored with the password. {enctype} is the type of encryption being employed, {salt} is the salt. Since you know the encryption type and salt, you can naturally reproduce the hash with the password they provide (thus authenticating the user).
A handy table of {enctype} values for crypt (for informational purposes):
ID | Method
─────────────────────────────────────────────────────────
1 | MD5
2a | Blowfish (not in mainline glibc; added in some
| Linux distributions)
5 | SHA-256 (since glibc 2.7)
6 | SHA-512 (since glibc 2.7)
And finally, how PHP lets you use them.
So, if you see a string like:
root:$6$foobar$JKLsdiuoilI/KSJHDKUyjh/SHDKJyUYW(....)
You know that you're dealing with SHA-512 and the salt is 'foobar' (and likely, the account is foobar too!).
It is (one) example of how salts are stored and associated with hashes. As SLaks said, don't restrict the salt to just ASCII. At the minimum you should be obtaining bytes from a PRNG or HRNG, falling back to time() only when no RNG is available.
No, You are doing it wrong. Use solardesigner's PHPASS in order to do the hashing and validation. Finally, never EVER use your own ad-hoc scheme, doing that is asking for trouble.

Categories