How to detect hashed password length? [closed] - php

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've started learning of password hashing. And I wonder how to detect hashed password length? Right now I'm experimenting with sha512 and one of the question is how to get user typed password length? Or is it impossible and I should validate user typed password length (e.g. if it is more than 8 characters) with javascript before sending a password to server? Could anybody explain me or suggest some learning material?

Hashing is a one-way function, which results in a string of constant length. (At least, the common ones, including sha-512. I don't know if constant length is guaranteed by the definition of hash.)
If you think about what a hash does, this should be obvious. A hash converts any string into a, say, 32 character string. Of course, not all information about an arbitrarily long string can be stored in a string of finite, predetermined length! Thus, according to the pigeonhole principle, there must exist hash collisions -- circumstances in which 2 strings hash to the same value. You can't fit n pigeons into n-1 pigeonholes!
Since we know there are infinite hash collisions, (because there are infinite possible strings), we can prove that at least 2 (really infinite) strings of different lengths will hash to the same value. Thus, since the length could be several (infinite) values from the same hash, you clearly can't get the correct length (or any real identifying information, using a good hash,) of the original string.
For example, the SHA-512 of "a":
1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
and of aldfksjhalkdfjh:
cde67871372c0a5e90ea3ae4b14ca3daa5ccd63f16b1f74181e2ab2d7bad2774a439f84d64d6c58eb77c17b03957ba98b897a14048b93cf18451500fd6f1ac41
Same length. The whole point of hashing is that it hides the nature of the original password. There's no reason to calculate the hash until you have validated that the password is legal, anyway. So, yes, server side validation is the way to go!
There are a lot of excellent resources out there for good password storing practices. You should take a look at those if you're planning to have a site with user passwords.

You cannot get any information about the password after it's been hashed. That's the entire point of doing so. Check your length before hashing on the server (not client-side in Javascript) and reject and don't hash the password if it doesn't pass validation.

It isn't possible to get the length of the original password by decrypting the hash, because that is the protection of your password. You can see yourself at most common websites, when you forget your password and want to retrieve it, you almost always get a random code to change your password to a new one, it isn't possible to just get the password already stored in the database, because it was hashed.
How storing and checking should be done:
You should convert a plain password to a hash, the hash will be stored in the database at register in the password field, everytime the user logs in, the plain password will be converted to a hash and checked if it matches the hash in the database. That way the password is already hashed when checking with database.

Ideally you should be sending the credentials over to the server over HTTPS and then hash the password with a salt that you can derived from the user data. The hashed password is then stored in your persistence and whenever the user credentials are presented, you re-create the hash based on the salt and then compare the hash against what you have in persistence.
If the question is regarding password strength, then you can use javascript to actually compute the length of the password as a client side validation itself.

you send it to the server unencrypted when the form submits or the AJAX request executes, then you check the length before you run the
$password = $_POST['password'];
$length = strlen($password);
hash("sha512", $password);
Good luck

count($string)
Depending on the hashed password type the lengths are always the same.
md5 is 32 i believe (not sure)

Related

I have accidentally used md5 to hash passwords, is it possible to create script to change everyone password? [duplicate]

This question already has answers here:
Is it possible to decrypt MD5 hashes?
(24 answers)
Closed 5 years ago.
Before knowing about just how dangerous md5 is, I have used it to store passwords. Md5 is terrible for security, and can easily be decoded. I now have 70,000 users registered in my database. Big mistake.
Now, since MD5 can be decoded into a string easily I was wondering if it is possible to loop through everyone's password in my MySQL database, decode it, and change it to a much stronger salt hashing system where it cannot be decoded to a string again. Would this be a viable option or even possible? Or is my only solution to do a hard database reset. Prompting users to change passwords would not be a good solution.
No. However, you can work around it, sort of:
Add a new field to your database to hold a second password.
Allow your users to log in as normal, with the MD5 system.
After they have successfully authenticated, you know their password. So now just use password_hash() on it and store it in the new field.
After some amount of time has passed, all active users will have their password encoded both ways.
Remove the MD5 authentication and replace it with password_verify().
Any users that hadn't logged in during the transition period will simply have to reset their password.
Keep the transition period as short as reasonably possible. This will allow your most active users to transition transparently without having to leave your system exposed for too long.
Note -- ultimately, you should have them change their passwords, as the current ones should be considered weak.
Edit for clarification:
You don't necessarily need to make a new password column. Since the hashes generated by password_hash() can be easily differentiated from those generated by md5(), you can simply use a strlen() check to determine which method to use. However, if you made your password field exactly the width of an MD5 hash string, then it's not going to be wide enough to hold the output of password_hash().

PHP and MySQL encrypting passwords with a Caesar shift? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a PHP login system where I check the username that the user inputted and cross check it with every username in my database. If there is a match it looks at the password and if there is a match again it will grant the user access to their profile. If not they will be redirected to the login screen. I currently store passwords as what they actually are, not encrypted or anything. I was wondering if it is possible to get the password the user inputs when signing up, use an algorithm I will programme such as replace each letter with its corresponding number(a bit more complicated than that obviously). I would then store the password as the output and when reading it in from the database it would be decrypted. Is this safe, if i make my own algorithm or can someone easily look at my code and decipher it?
Do not store encrypted or (shudder) plain text passwords.
If you need to store a password value, store the return from a cryptographic hash function. There's no need to "roll your own" cryptographic hash algorithm. (The strength of a cryptographic algorithm is not produced by keeping the algorithm "secret".)
Cryptographic hash algorithms are the workhorse of modern security.
https://en.wikipedia.org/wiki/Cryptographic_hash_function
When you need to test a password (by comparing a submitted password to a stored password value), just run the submitted password (to be tested) through the same cryptographic hash function, and take the return from that and compare to the stored hash value. If the hash values match, then there is an extremely high probability that the plaintext passwords match. If the hashes don't match, then you are guaranteed that the passwords don't match.
To directly address the specific questions you asked:
Q: Is [my proposed implementation] safe?
A: The short answer is no, it's not safe. The first part of my answer describes a better approach to handling password tokens for authentication.
Q: If i make my own algorithm or can someone easily look at my code and decipher it?
A: The strength of a cryptographic algorithm is not found in keeping the code "secret".

Is storing a salt in the MySQL table secure? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best way to prevent SQL Injection in PHP
The necessity of hiding the salt for a hash
I'm very new to MySQL and PHP, and have started self-learning it over the past couple of days and today I was looking at encryption for passwords etc. I've been looking through many webpages with information on the topic and most of them are saying to generate a random salt for every entry in the table (which I understand, you don't want the same salt for every entry) and this salt should then be stored in the table alongside the entry.
From what I've understood (correct me if I'm wrong), the encryption of the password doesn't prevent hackers from accessing it, rather just masks the true value if they do get access to the database. Surely if this is the case, you wouldn't want to store the salt in the table too - if the hacker has accessed the database and can see the encrypted data, showing him the salt just makes his job of decrypting infinitely easier?
The salt isn't used to encrypt. Instead, it goes (together with the password) into a hash function. That way, nobody (not even your application) can determine the password, but you can verify a password.
The salt is then used to require the attacker to attack each password hash individually (if the attacker wants just one password, the salt doesn't help in any way). Thanks to rainbow tables, it is fairly easy to compute the outputs of the hash function for common passwords.
The salt value is not secret, and can be safely stored in a MySQL database (or even published).
The purpose of the salt is to prevent the use of Rainbow tables.These would allow a hacker to have generated a large number of pre generated hashes for certain passwords. By appending the salt to the password before it is hashed the hash is completely different than the original password.
password => 5f4dcc3b5aa765d61d8327deb882cf99
password+saltvalue => 1d7dc54c316b11f3a38cc24fa68e2b6a
thus they would need to recreate the hash for each salt value which is unpractical.
It is perfectly fine to store the salt in the way that you are planning to. In fact it is fine to allow the attacker to see the salts. The purpose of the salt is to prevent people from being able to use prebuilt look up tables called rainbow tables by extending the size of the message space. All the salt does is make them throw out any precomputation and solve the whole problem which is time consuming but certainly possible (especially for hashes like md5 -- you should move to sha256)
You want to use different salts for each user so that an attacker would have to do the full amount of work for each password they recover rather than just generate a new table based on a single salt.
You can consider salt as something 'semi unique', it really does not have to be additional column called salt. Username, user email is also a kind of salt. So they are actually stored in db, next to hashed password. One problem with this approach occur when user decide to change a username or email.

SHA Encryption - Are Salts Really Needed?

I'm using Jquery SHA512.js to sent encrypt and send a username and password to the server.
At the server I'm doing the following to create my DB stored HASH:
$dbhash = = hash('sha256',(hash('sha512',$user) . hash('sha256',$extremesalt)));
This all works fine.
My Question is what value is the Salt?
At the point the Salt is applied to the password, the password is already on the server and not in transit across the Internet. Also the Salt is stored next to the password hash.
Therefore it appears someone would need to get my table with hash's and if they did they could also get the salt and the rest of my code and do what they wanted with my site in general.
I can see its good to apply a salt and I will do so but as it only occurs on the server and not from the browser to the server I question its value. Am I missing something?
One other question - is it possible to apply a salt from the browser to the server. I assume not or at least if you did it would be visible if one checked the source (eg: in my cause visible in jquery). Thus of no real value.
thx
The point of the salt is to make it harder to see if 2 people's passwords are the same. One thing about SHA is that it's not easily reversible. Most attacks involve generating hashes for common passwords so for reasonably complicated passwords it becomes harder especially with salts (some people use usernames as salts, others use randomly generated numbers). Usually you want to do this on the server side code (I don't think it's safe to do on browser code). You should also never store the actual password on the server you only store the hash (and maybe the salt if you don't already know it)
Upon a second look I see that you're using 2 hashes one after the other 256 and then a 512. This is a bad idea, use one and stick with it. You waste time computing multiple hashes.
Mixing hashes like that is rather pointless. Taking an sha512 hash and running it through sha256 necessarily cuts the keyspace in half, so all you've done is waste cpu time and double the odds of a collision. The odds will still be vanishingly small/microscopic, but it's still something to consider.
The salt is there as a butt-covering mechanism. If for some reason your database were to leak (e.g. a dump file got "lost"), it would be trivial to generate an sha256/512 rainbow table of common passwords and see if there's any hits on your table. The hash is there to make it far more expensive to generate a rainbow table. e.g. "password" is easy to hash and check for. "password#^$##%#^Y###$##^%$^Y%%$" is far less likely to be rainbowed.
I don't know your app, but wouldn't you want to just send the username/pwd to the server using SSL and let the public key encryption of SSL take care of the encryption for you. The server can then generate an appropriate hash to either store the hashed password or to compare to a previously stored hash for verification.
$dbhash = = hash('sha256',(hash('sha512',$user) . hash('sha256',$extremesalt)));
Should be (no need for double hashing)
$dbhash = = hash('sha512',$pass + $salt);
Where pass is the password and salt is something unique about the user (userid for example). If you opt for random value you need to store it with the hash.

What is md5() for?

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).

Categories