[php] SHA1 vs md5 vs SHA256: which to use for a PHP login?

I'm making a php login, and I'm trying to decide whether to use SHA1 or Md5, or SHA256 which I read about in another stackoverflow article. Are any of them more secure than others? For SHA1/256, do I still use a salt?

Also, is this a secure way to store the password as a hash in mysql?

function createSalt()
{
    $string = md5(uniqid(rand(), true));
    return substr($string, 0, 3);
}

$salt = createSalt();

$hash = sha1($salt . $hash);

This question is related to php login md5 sha1 sha256

The answer is


MD5 is bad because of collision problems - two different passwords possibly generating the same md-5.

Sha-1 would be plenty secure for this. The reason you store the salted sha-1 version of the password is so that you the swerver do not keep the user's apassword on file, that they may be using with other people's servers. Otherwise, what difference does it make?

If the hacker steals your entire unencrypted database some how, the only thing a hashed salted password does is prevent him from impersonating the user for future signons - the hacker already has the data.

What good does it do the attacker to have the hashed value, if what your user inputs is a plain password?

And even if the hacker with future technology could generate a million sha-1 keys a second for a brute force attack, would your server handle a million logons a second for the hacker to test his keys? That's if you are letting the hacker try to logon with the salted sha-1 instead of a password like a normal logon.

The best bet is to limit bad logon attempts to some reasonable number - 25 for example, and then time the user out for a minute or two. And if the cumulative bady logon attempts hits 250 within 24 hours, shut the account access down and email the owner.


As Johannes Gorset pointed out, the post by Thomas Ptacek from Matasano Security explains why simple, general-purpose hashing functions such as MD5, SHA1, SHA256 and SHA512 are poor password hashing choices.

Why? They are too fast--you can calculate at least 1,000,000 MD5 hashes a second per core with a modern computer, so brute force is feasible against most passwords people use. And that's much less than a GPU-based cracking server cluster!

Salting without key stretching only means that you cannot precompute the rainbow table, you need to build it ad hoc for that specific salt. But it won't really make things that much harder.

User @Will says:

Everyone is talking about this like they can be hacked over the internet. As already stated, limiting attempts makes it impossible to crack a password over the Internet and has nothing to do with the hash.

They don't need to. Apparently, in the case of LinkedIn they used the common SQL injection vulnerability to get the login DB table and cracked millions of passwords offline.

Then he goes back to the offline attack scenario:

The security really comes into play when the entire database is compromised and a hacker can then perform 100 million password attempts per second against the md5 hash. SHA512 is about 10,000 times slower.

No, SHA512 is not 10000 times slower than MD5--it only takes about twice as much. Crypt/SHA512, on the other hand, is a very different beast that, like its BCrypt counterpart, performs key stretching, producing a very different hash with a random salt built-in and will take anything between 500 and 999999 times as much to compute (stretching is tunable).

SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

So the choice for PHP is either Crypt/Blowfish (BCrypt), Crypt/SHA256 or Crypt/SHA512. Or at least Crypt/MD5 (PHK). See www.php.net/manual/en/function.crypt.php


Use argon2i. The argon2 password hashing function has won the Password Hashing Competition.

Other reasonable choices, if using argon2 is not available, are scrypt, bcrypt and PBKDF2. Wikipedia has pages for these functions:

MD5, SHA1 and SHA256 are message digests, not password-hashing functions. They are not suitable for this purpose.

Switching from MD5 to SHA1 or SHA512 will not improve the security of the construction so much. Computing a SHA256 or SHA512 hash is very fast. An attacker with common hardware could still try tens of millions (with a single CPU) or even billions (with a single GPU) of hashes per second. Good password hashing functions include a work factor to slow down dictionary attacks.

Here is a suggestion for PHP programmers: read the PHP FAQ then use password_hash().


Here is the comparison between MD5 and SHA1. You can get a clear idea about which one is better.

enter image description here


An md5 encryption is one of the worst, because you have to turn the code and it is already decrypted. I would recommend you the SHA256. I'm programming a bit longer and have had a good experience. Below would also be an encryption.

password_hash() example using Argon2i

<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
The above example will output something similar to:

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0

Let's assume the next point : the hackers steal our database including the users and password (encrypted). And the hackers created a fake account with a password that they know.

MD5 is weak because its short and popular and practically every hash generation without password is weak of a dictionary attack. But..

So, let's say that we are still using MD5 with a SALT. The hackers don't know the SALT but they know the password of a specific user. So they can test : ?????12345 where 12345 is the know password and ????? is the salt. The hackers sooner or later can guess the SALT.

However, if we used a MD5+SALT and we applied MD5, then there is not way to recover the information. However, i repeat, MD5 is still short.

For example, let's say that my password is : 12345. The SALT is BILLCLINTON

md5 : 827ccb0eea8a706c4c34a16891f84e7b

md5 with the hash : 56adb0f19ac0fb50194c312d49b15378

mD5 with the hash over md5 : 28a03c0bc950decdd9ee362907d1798a I tried to use those online service and i found none that was able to crack it. And its only MD5! (may be as today it will be crackeable because i generated the md5 online)

If you want to overkill then SHA256 is more than enough if its applied with a salt and twice.

tldr MD5(HASH+MD5(password)) = ok but short, SHA256 is more than enough.


What people seem to be missing is that if the hacker has access to the database he probably also has access to the php file that hashes the password and can likely just modify that to send him all the successful user name password combos. If he doesn't have access to the web directory he could always just pick a password hash it, and write that into the database. In other words the hash algorithm doesn't really matter as much as system security, and limiting login attempts also if you don't use SSL then the attacker can just listen in on the connection to get the information. Unless you need the algorithm to take a long time to compute (for your own purposes) then SHA-256 or SHA-512 with a user specific salt should be enough.

As an added security measure set up a script (bash, batch, python, etc) or program and give it an obscure name and have it check and see if login.php has changed (check date/time stamp) and send you an email if it has. Also should probably log all attempts at login with admin rights and log all failed attempts to log into the database and have the logs emailed to you.


Everyone is talking about this like they can be hacked over the internet. As already stated, limiting attempts makes it impossible to crack a password over the Internet and has nothing to do with the hash.

The salt is a must, but the complexity or multiple salts doesn't even matter. Any salt alone stops the attacker from using a premade rainbow table. A unique salt per user stops the attacker from creating a new rainbow table to use against your entire user base.

The security really comes into play when the entire database is compromised and a hacker can then perform 100 million password attempts per second against the md5 hash. SHA512 is about 10,000 times slower. A complex password with today's power could still take 100 years to bruteforce with md5 and would take 10,000 times as long with SHA512. The salts don't stop a bruteforce at all as they always have to be known, which if the attacker downloaded your database, he probably was in your system anyway.


I think using md5 or sha256 or any hash optimized for speed is perfectly fine and am very curious to hear any rebuttle other users might have. Here are my reasons

  1. If you allow users to use weak passwords such as God, love, war, peace then no matter the encryption you will still be allowing the user to type in the password not the hash and these passwords are often used first, thus this is NOT going to have anything to do with encryption.

  2. If your not using SSL or do not have a certificate then attackers listening to the traffic will be able to pull the password and any attempts at encrypting with javascript or the like is client side and easily cracked and overcome. Again this is NOT going to have anything to do with data encryption on server side.

  3. Brute force attacks will take advantage weak passwords and again because you allow the user to enter the data if you do not have the login limitation of 3 or even a little more then the problem will again NOT have anything to do with data encryption.

  4. If your database becomes compromised then most likely everything has been compromised including your hashing techniques no matter how cryptic you've made it. Again this could be a disgruntled employee XSS attack or sql injection or some other attack that has nothing to do with your password encryption.

I do believe you should still encrypt but the only thing I can see the encryption does is prevent people that already have or somehow gained access to the database from just reading out loud the password. If it is someone unauthorized to on the database then you have bigger issues to worry about that's why Sony got took because they thought an encrypted password protected everything including credit card numbers all it does is protect that one field that's it.

The only pure benefit I can see to complex encryptions of passwords in a database is to delay employees or other people that have access to the database from just reading out the passwords. So if it's a small project or something I wouldn't worry to much about security on the server side instead I would worry more about securing anything a client might send to the server such as sql injection, XSS attacks or the plethora of other ways you could be compromised. If someone disagrees I look forward to reading a way that a super encrypted password is a must from the client side.

The reason I wanted to try and make this clear is because too often people believe an encrypted password means they don't have to worry about it being compromised and they quit worrying about securing the website.


Use SHA256. It is not perfect, as SHA512 would be ideal for a fast hash, but out of the options, its the definite choice. As per any hashing technology, be sure to salt the hash for added security.

As an added note, FRKT, please show me where someone can easily crack a salted SHA256 hash? I am truly very interested to see this.

Important Edit:

Moving forward please use bcrypt as a hardened hash. More information can be found here.


Edit on Salting:

Use a random number, or random byte stream etc. You can use the unique field of the record in your database as the salt too, this way the salt is different per user.


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to login

How to center a component in Material-UI and make it responsive? SQLSTATE[HY000] [1698] Access denied for user 'root'@'localhost' Angular redirect to login page Swift add icon/image in UITextField SQL Server : login success but "The database [dbName] is not accessible. (ObjectExplorer)" vagrant login as root by default Node.js https pem error: routines:PEM_read_bio:no start line EditText underline below text property Given URL is not allowed by the Application configuration Facebook application error how to get login option for phpmyadmin in xampp

Examples related to md5

Hashing a file in Python How to convert password into md5 in jquery? How do I calculate the MD5 checksum of a file in Python? encrypt and decrypt md5 How to generate an MD5 file hash in JavaScript? SHA-256 or MD5 for file integrity How to reverse MD5 to get the original string? Calculate a MD5 hash from a string Calculate MD5 checksum for a file How to convert md5 string to normal text?

Examples related to sha1

How to add SHA-1 to android application Check if my SSL Certificate is SHA1 or SHA2 Hashing a file in Python Is it possible to decrypt SHA1 Hashing with SHA1 Algorithm in C# Simple (non-secure) hash function for JavaScript? How to SHA1 hash a string in Android? Java String to SHA1 Is calculating an MD5 hash less CPU intensive than SHA family functions? SHA1 vs md5 vs SHA256: which to use for a PHP login?

Examples related to sha256

PHP salt and hash SHA256 for login password Are there any SHA-256 javascript implementations that are generally considered trustworthy? Mismatch Detected for 'RuntimeLibrary' SHA-256 or MD5 for file integrity Hashing a string with Sha256 How to hash some string with sha256 in Java? Generating a SHA-256 hash from the Linux command line Hash String via SHA-256 in Java Generate sha256 with OpenSSL and C++ How long is the SHA256 hash?