This is the question: It`s possible to break a sha1(md5('password')) password ?
Or how it`s better md5 in sha1 or sha1 in md5 ?
Thanks!
multiple hashing doesnt further secure your password. just use a secure, salted hash.
check out http://php.net/hash
According to Wikipedia's MD5 article:
"The security of the MD5 hash function is severely compromised."
So adding MD5 to a SHA1 is not gonna make your thing more secure. I would even say that hashing an already hashed thing is not gonna make it more secure either.
A common mechanism that many people use for storing passwords is a salt encription over a hashed string.
Since no one answered the original question: Yes, it is possible.
As to the second question: md5(sha1('password')) will actually reduce security compared to just using sha1 because the hash size will be reduced. And the other way around doesn't help either.
Always use salting!
md5 will get you a 32 characters string.
sha1 will get you a 40 characters srings.
But, in both cases, those strings will only contain hexadecimal characters, which means only 16 possible values for each position : 0-9 and a-f
I don't think using md5+sha1 (no matter in which order you call those) is such a good idea : using only one of those on your password will probably be safer.
Just consider :
You can have, say, at least 8 characters in your password
Each of those 8 characters can be a letter (upper or lower case), a number, a special character ; which means at least something like 75 possibilities for each position
Don't you think that would make more possible combinations than 32 hexadecimal characters ?
Just use one hashing function, and salt your password.
Wrapping the hashing functions inside each other isn't going to make your hashes any more secure. A rainbow table could still be constructed to allow an attacker to read a large number of passwords in your database.
This is assuming of course that they have access to your code, but they probably do since by this stage they have access to your database.
Using two hashes does not make your algorithm safe; hashing once, using the best (with more bits) algorithm AND adding some salt does. For example:
sha1('This is some salt' . $string . 'othersalt')
This is much safer against rainbow tables. I mean: not completely safe, as the attacker could build a rainbow table, but it is safer because common rainbow tables won't work. Also notice that both algorithms have been cracked: I strongly suggest you to use SHA-2, e.g. sha-128 or sha-256. They still haven't been broken.
Last thing: always salt hashes against rainbow tables. Always use the best hashes: SHA-3 is coming, you may want to use it.
Related
So I know that MD5's are technically a no-no in new applications, but I randomly had a thought of this:
Since
md5($password);
is insecure, wouldn't
md5(md5($password))
be a better alternative?
would it keep getting more secure the more I use it? Say if I made a function like this
function ExtremeEncrypt($password)
{
$encryptedpass = md5(sha1(md5(md5($pass))));
return $encryptedpass;
}
Would this function be a good alternative to say using a random salt for every account like vbulletin does.
Double hashing a string does nothing except limit your key space and make collisions more likely. Please don't do this. Double md5 hashing is actually less secure than a single hash with some attack vectors.
A better option would be to use the password_hash function in php 5.5 or ircmaxell's password_compat library for earlier php versions.
First of: hash and encryption are not the same. Hash is a one-way function while encryption expects data could be decrypted.
You should not try to invent your own solution when it comes to security. In PHP, since 5.5 version, there is native solution called Password Hashing. md5() is insecure and you should be aware of that.
If you have PHP below 5.5 version, you should use salt to hash & store your passwords.
You have lots of answers here and they are accurate but they don't really explain why.
MD5 is a hashing algorithm. What a Hashing algorithm does, is take a long piece of data and analyse it cryptographically in a way that creates a smaller piece of data. So from ABCDEFGHIJKLMNOPQRSTUVWXYZ with my custom hash algorithm I might create a single digit hash 5.
When that is done, you lose information - ABCDEFGHIJKLMNOPQRSTUVWXYZ contains far more information than 5 and there is no way to make the translation the other way.
The problem with hashing in a way that only allows an outcome of 0-9 ( this is effectively a Checksum ) is that if you take two pieces of text, the chances are quite high that they will have the same hash. So maybe with my algorithm ZZZZZZZZZ will also produce a hash of 5. This is what is termed a Hash Collision.
Now what happens if I take the hash of my hash? Well, my starting point is already very low information - the most it can possibly be is one of ten digits, so the chance of a collision is now exceedingly high. Supposing when my hash algorithm runs on numbers it returns 1 if it is odd and 0 if it is even- so if I have a hash of ABCDEFGHIJKLMNOPQRSTUVWXYZ which comes to 5 then I have a 10% chance of a collision. But if I make a hash of that hash, I will now have a 50% chance of a collision.
The trick of cryptography is hiding information in such an enormous possible space that it is unbelievably hard to find. The more you shrink that possible space, the less well hidden your information is.
Short answer: No.
md5 is easy to break using brute-force. Adding additional layers of hashing only slows down a brute-force attack linearly.
First of all md5 isn't really encryption, because there isn't a decryption method to it. It's called hashing.
The standard practice is to salt your passwords:
$salt = [some random/unique number, people usually use user_id or timestamp]
$hashed_password = sha1($salt . $password)
Remember that you need to know the salt, hence usually it means storing it along with the hashed password.
You can have multiple salts, and arrange them however you like.
I'm storing username and password in a MySQL database and have them hashed using MD5. However, I'm only using the standard PHP function without any modification. Now, I read that MD5 is broken. How are you doing it? Do you run it several times through a different hash mechanism or add some form of salt?
I'm amazed how people jump on the bandwagon of "damn, it's broken, I won't use it!", don't do the same mistake.
You can't make the MD5 better. Even using SHA-1 is vulnerable to same type of attacks as MD5.
Using bcrypt will use A LOT more CPU than MD5 and SHA algorithms.
MD5 is designed to be fast, same as SHA. bcrypt isn't and it allows for more permutations, which makes it harder for someone to try to decrypt the original string.
You need to know why MD5 is considered "broken".
Because it's fast to calculate a rainbow table of passwords up to 6 characters in length.
Using today's computing power, one can create an array of characters and MD5 all permutations and map them to the original string. That's how you get a rainbow table. If someone downloads your database and then compares passwords to their rainbow table - they can obtain users' original password. Reason why this is dangerous is because people use same passwords for many things - including paypal and other money processing service. That's why you use so-called salt. That makes it even harder to obtain the original string, so salting your users' passwords (let's say by reversing them and MD5-ing the reversed input) will make it harder for the attacker to revert the hash to original string.
Because of collisions.
What's a collision? If you give hashing function two different strings and it returns the same hash - that's a collision. How does it translate to web and hashing passwords for logins? If you have the same hash for user1/password1 and user2/password2 - they could log on as someone else. That's where collisions play the role in security.
Reason why MD5 is considered broken is because MD5 returns same hash for strings that differ in small percentage. And it's not easy to calculate what that string might be!
From mathematical point of view - yes, it's "broken" because if your string has 100 chars and it differs from other string in 10 chars (10% difference) - you get the same hash.
What applies for MD5 applies for ALL hashing algorithms. In the end, all of them don't have infinite number of possible hashes.
However, some of them (like MD5) have less possible hashes and execute faster.
In the end, if someone got to your database - you have a bigger problem than using MD5 instead of bcrypt or SHA1.
Add a salt to each password stored that's not equal for every password
Simply use MD5("yoursite.com".$string);
MD5 is not decryptable. The only possible way to crack it is through hash tables that brute force everything. If you add a random string that only you know they cant crack it.
If you're worried about password security then you should use SHA1() (or alternative) rather than MD5(). Whilst MD5 is not decryptable, it can be beaten by either rainbow tables or matching the hash.
Salts will work against rainbow table but not against matching the hash which has been achieved with MD5.
There are a couple of things you should do.
Use SHA instead of MD5. SHA is more cryptographically secure than MD5. The more bits the better!
Use a salt. This makes rainbow table attacks more difficult.
Strengthen your key by calculating the hash like as follows:
:
function strenghtened_hash( $password, $salt, $n ) {
$crypted = sha( $password . $salt );
for( $i = 0; $i < $n; $i++ ) {
$crypted = sha( $crypted . $password . $salt );
}
return $crypted;
}
Now you should be in good shape!
You might be better off using using bcrypt for password storage to prevent rainbow-table attacks in case the bad guys get hold of your DB.
At the very least, dump MD5 (although computationally fast, not very secure these days) and use something a little more secure like SHA256 with a long salt.
Switch to a different hash mechanism (you can do it incrementally as people log in) and definitely use a (different for each user) salt!
You can use a thing called a salt. It means that you also save this salt into you database. It's a random string which is more or less long and is unique for each user.
Then, to check the password, you do something like this:
<?php
$crypted = md5($salt.$passwordFromForm);
if($crypted == $passwordFromDB) {
// user logged on
}
?>
You can make MD5 or any hashing function more strong by a method called "loop-hashing" i wrote about , read it here ,Good method to encrypte data, , using a loop "for" or "while" to encrypte password a lot of times with a random generated key number , really it's strong and so easy , so won't be scare from crackers again , no one can crack an encrypted "loop-hash" at the moment with the available databases .
I know MD5's safety is under question lately and this is the reason a lot of people are using salt (I dont understand this at all btw) but I was wondering if you wanted to easily implement a safe system in php can you just md5 something twice?
like test > 098f6bcd4621d373cade4e832627b4f6 > fb469d7ef430b0baf0cab6c436e70375
So basically:
$val = 'test';
$val = md5($val);
$val = md5($val);
Would that solve the whole rainbow security stuff? Is there an easy/noob proof way of making secure database passwords in php?
Hashing twice makes little real sense and doesn't accomplish much. In general, however, multiple hashing can make some sense. For example, if you hash enough times to take something like 100 ms (or so, depending on hardware) it can help a little. The basic idea of it is pretty simple: adding 100 ms to a normal login is a barely noticeable delay -- but if you're trying to build something like a table for a dictionary attack, multiplying the time by something like a thousand (or whatever exactly it works out to) starts to make a real difference -- a table that you could normally compute in (say) a day, takes a few years instead. That's enough difference that anything but really serious attackers will often give up (or just get bored) long before they finish the job.
Salt is an entirely separate tool. Using it does not make up for weakness in the underlying hash function. The idea here is that the size of a table for a dictionary attack becomes substantially larger (e.g., for a one-byte salt, 256 times larger). The salt is not normally kept secret, but it's relatively random, so an attacker who's doing a dictionary attack can't just hash each word as-is, but has to take each possible salt value into account. At the risk of repetition: it deals with a weakness in how (most) people pick passwords, not any weakness in the hash function itself.
If you don't believe in MD5, you can try a higher algorithm by using the hash() function:
$hash1 = hash('sha1', 'The string to hash by SHA-1');
$hash2 = hash('sha256', 'The string to hash by SHA-256');
$hash3 = hash('sha512', 'The string to hash by SHA-512');
$hash4 = hash('ripemd160', 'The string to hash by RIPEMD-160');
In my opinion it does not make sense to hash twice.
EDIT: Fixed typo in last line of code.
Whether or not you use the MD5 algorithm...
No, an attacker can always have two rainbow tables (one for the extra level of hashes, and one for the passwords). And from another answer of mine:
[...] it still just requires the password and nothing more to crack. In other words, you are just applying the hashing functions to the same thing a few times more.
You use a salt to make it more difficult for the attacker to get at your passwords, because then he would need to know the salt so that he can use it in computing the hashes for your passwords.
Storing passwords securely is tricky, most the advice posted here is not accurate. So I will defer to Thomas Ptacek's widely cited post on the subject: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
For the record, I evaluated that
$val = 'test';
$salt='somerandom!!aa##9900';
$val = md5($salt.$val);
$val = md5($val);
Its pretty safe. The secret is in the salt.
However, md5 is short so the chances of concurrences are "high" (one in 1.208.925.819.614.629.174.706.176 = 32^16, 32 words with an hexadecimal each one)
I am going to generate a random password for my users. Probably I will use salt and sha1 method. But I found that there are other version of sha1, like sha256, sha512 etc.
What is the differences between the sha versions? Which one better, more secure, and faster (performances)? Which one should I use??
EDIT:
I am php user, thanks :)
Password generation is not as straightforward as you may think. For instance, if you're generating a password for a site which can be accessed from a mobile phone (or any device with only a numerical keyboard) you should ensure that no two consecutive characters in your password are on the same key since that would be a huge UI flaw.
An example: consider dfe4Pl7 as a password. In order to type it in, a used should press 3 once, than wait, then press 3 three times, then wait again and press '3' two more times. This sucks.
In more general terms, password should be generated so that misinterpretation is avoided as much as possible. For example, I'd personally avoid including 1's and l's, 0's and O's, etc.
The bottomline is: hashing algorithms will be of a very little help here. What you need is a good random-number generator and a UI-wise solid generation algorithm.
You are confusing two issues here. Random password generation, which is basically picking random symbols of a certain (minimum) length, and password storage, which in practical terms involve storing a hash of the password with a salt so that the plaintext password can't be discover just by reading the database.
Generation
To pick random symbols, you have an array of all the symbols, get a random number and subscript into the array using that number as index to return a symbol. This is what Kane Wallmann suggested earlier. However, for security related application such as password generation, one need a cryptographically strong pseudo-random number generation, which rand() is not.
Storage
As noted earlier, password shouldn't be stored in plaintext in the database. Otherwise, anyone with access to it can just read it and know what the password of any and all particular user password are. What happen is a hash of the password is store instead. When a user attempt to login, their password is hash and compare to the value in the database to see if it's the same. The hashing function is what's call a one-way function. You can hash the password to get a hashed value, but you can't get the password from the hash value without trying all possible combination to see if it matches. (At least, that's the idea anyway.) It's more complicated than that of course, since hash value output is fixed length, whereas the possible input while in practical terms isn't infinite is definitely more than the possible number of output.
Now, where salt comes in is because simple hashing of the password alone isn't secure either. For one, such a method would give the same hashed value for any two users with the same password. Compromise of one account would result in the compromise of the other. Secondly, what an attacker can do is to build what is called a rainbow table ahead of time. While this take time, it only have to be done once for any storage algorithm, and he or she don't have to do it themselves. The work can be spilt over many computers, and there's in fact websites on the internet where you can download such rainbow tables for weak password hashing system such as LM and NTLM. After that, the attacker can just look up any particular hash value against the table and determine the plaintext password. So to protect against that, a random (per user) salt value is added to the password before it is hashed. This makes the input different even for the same password, so prevent the first problem. It also mitigate against the second problem if the salt & password combined is long enough as the length of the input is such that it would become computationally infeasible to brute force it.
As to the question of which particular SHA, or for that matter, other hashing algorithms to use. SHA is a US NIST standard, and are acknowledged to be pretty good. There's been a little theoretical breakthrough into SHA-1, but in practice it's still secure enough for most purpose. The SHA-2 algorithms are better than SHA-1, with no known breakthrough. Which variant to choose are down to various things including size. They produce different length output, and different amount to calculate because of the size difference. PHP have native implementation of SHA-1, SHA-256, 384, and 512, among a number of others hashing algorithms.
After all that, in practice, which of the SHA algorithms you choose probably doesn't matter as the weak point in your system are likely elsewhere. Users writing down their passwords. Users using the same password across different systems. Programming flaw that allow things like XSS and SQL injection. Etc. etc.
Encryption algorithm security doesn't mean anything if you are simply using them to make random letters and numbers for a password. You are better off making a random password function, it would be MUCH more efficient.... Why are you salting anyway?
Here is a SIMPLE password generator written in PHP.
function RandomPassword( $length )
{
$characters = "abcdefghjklmnpqrstuvwxyz23456789";
$result = "";
for( $i=0; $i < $length; $i++ )
{
$result .= $characters[ rand( 0, strlen( $characters )-1 ) ];
}
return $result;
}
NOTE: i,1,0 and o are intentionally missing as they are easily mistaken as each other.
here's the wiki you can read about sha
there it talks about sha-2 family being algorithmically similar, however sha-1 is more popular.
How strong do salts need to be?
At the moment I use this function to generate a "unique" salt upon user registration:
$salt = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'), 0, 12);
I then hash it with sha1 along with the password.
What do you think?
PS. I'm not planning on getting MySpace big.
When it comes to security it's not really an issue of how strong your salt is, it's an issue of how computationally expensive the hashing function is. SHA1 and MD5 are cheap. If you're going to stick with fast (weak) hashing functions - and this may be perfectly acceptable for small sites, I don't mean to imply otherwise - then I wouldn't worry about just how cryptographically-random the salt is. As long as it's random, it'll serve its purpose of eliminating precisely one attack vector (rainbow tables).
The purpose of random salts is to ensure that a simple rainbow table won't work to decrypt the passwords, should the database table be leaked. If each record has its own salt, a new rainbow table would be needed for every single row.
Your shuffling approach is fine. The main point is for the salts to be DIFFERENT for each record, so that a single rainbow table won't compromise the whole table of passwords. The "strength" of the salts isn't as important.
The method of shuffling characters and taking the first 12 is equivalent to picking (without repetitions) 12 characters when the order matters. You have 36!/(36-12)! ~~ 2^59 possible ways of doing this.
If you pick all 12 elements (with possible repetitions) from the set of 36 letters, there are 36^12 ~~2^62 possible ways of doing it.
So in the method you used you end up with around 59 bits of entropy. I would say it's sufficient for any application and gives only 8 times less combinations that picking elements with repetitions.
How strong a salt is all depends on how worried you are about security. You could simply salt it with the username (not very strong,) or you could generate a unique salt for each user, as you did.
If you're really worried, you could also create an encryption key, and encrypt each of these.
The more you add to it, the stronger it will, be, obviously. It's all just how worried about security you are.
You could try adding some special characters to that salt and it would be a lot stronger.
Salt lengths of 12 characters or more are difficult to crack but you can easily make your salts stronger by using other characters too i.e. upper case letters and special characters.
You are already salting your hash and ensuring each record has it's own individual salt which is very important.
Any sufficiently random salt is strong "enough". The more randomness and more characters your salt has, the better for the hash, but anything that's several characters long and random works.
Here's some interesting links on password security:
http://en.wikipedia.org/wiki/Password_cracking
http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
http://www.codinghorror.com/blog/archives/000953.html