1

I have been researching the best way to encrypt my password into my mySQL database, but I haven't been able to pin-point the best encryption for passwords.

  • md5() is said to be flawed because of various security reasons which I do not know, but is somehow used by WordPress. Why is this function so criticized?

  • sha1() is just another function inspired by md-series with more computational complexity.

  • password() seems to be advised to use.

  • and the PASSWORD() in MySQl

  • then, the new function hash() which came into use in PHP 5.1.2. and newer versions

In what way is MySQl PASSWORD() different from other php functions named above?

Explosion
  • 65
  • 1
  • 3
  • 12

2 Answers2

10

First of all, please note that most people do not encrypt (as you wrote) passwords into their databases. Encryption, whether symmetric or asymmetric, means that the data could be decoded again. Encrypting passwords would be a very bad concept (at least if there would be a common key for all of them) because the decryption keys would have to be stored somewhere, and if an attacker would get hold of them, he could immediately decrypt all passwords.

What you want to do is called hashing. The hash of a password is derived from the password by applying a hashing function to the password. The key point here is that this process cannot be reverted, i.e. there is no mathematical method to get the password back from the hash.

Having said this:

  • MySQL's SET PASSWORD and PASSWORD() are deprecated. They will be removed in future versions of MySQL. If you want your application to run with future versions of MySQL, don't use SET PASSWORD and PASSWORD().

  • MD5 and SHA1 are definitely not the way to go; they are considered broken.

  • The SHA-2 family (e.g. SHA256, SHA512) is considered safe in a mathematical sense. Nevertheless, it has low computational cost / high speed, and today's consumer GPUs can compute multiple billions of SHA-2 hashes per second. Thus, for hashing passwords, other hashing functions like bcrypt, pbkdf2 or scrypt (which is my current favorite) are appropriate; these are designed to be slow (how slow can be adjusted which is a big advantage in the future) and (in case of scrypt) to consume much memory which makes hardware (ASIC, FPGA) based attacks more difficult.

I don't know PHP, but most languages have a function called crypt() or encrypt() or the like which uses the crypt() API of the underlying O/S (in Linux: glibc), so you could use this as a starting point, but only if it already provides one of the slow hashing algorithms (which mostly is not the case).

MySQL has a function called ENCRYPT() which also uses the OS's crypt(), but it is deprecated as well. MySQL also has a SHA2() function, but as mentioned above, this might not be sufficient. Unfortunately, MySQL (AFAIK) does not provide a BCRYPT(), PBKDF2(), SCRYPT() or any other well-known slow hashing function.

Since you should use one of the slow hashing algorithms, and since neither the OS's crypt() (in most cases) nor MySQL provide any of them, you should do the hashing in your back-end application. As said above, I don't know PHP, but I am quite sure that there is an implementation for at least one well-known slow hashing algorithm (which does not depend on the underlying OS's / libc's crypt()).

By the way, there will be no differences regarding the result between various implementations of hashing algorithms. For example, if you apply SHA512 to a string using your favorite programming language, the result will be the same as if you apply SHA512 to that same string using MySQL. The same is true for the other hashing algorithms, including the slow ones. There may be a performance difference, though.

That basically means that, if you now do the hashing in your application back-end, you can do it later in MySQL as soon as MySQL provides the slow hashing algorithm you are using. You can switch forth and back between hashing in the application back-end and hashing in the database withouth having to re-compute all stored hashes and without losing data.

Additional rules of thumb:

  • Don't even think of implementing your own login / password system before you have fully understood all references I gave.

  • If you are for some reason forced to use any other hashing algorithm than a slow one, always use salting, of course with a different salt per password. While some people proclaim that this is useless, I don't think so. It still will make attacks more difficult (compared to hashing without salt). But attacks against fast hashing algorithms like the ones from the SHA-2 family, whether salts are used or not, will still be extremely easy and efficient compared to attacks against one of the slow hashing algorithms.

Finally, here is a blog entry which should get you started. This will give you a feeling about what's important, but you'll have to do further research (it's four years later now ...).

Binarus
  • 4,005
  • 3
  • 25
  • 41
  • Thank you for the answer ,was looking for this. – Explosion Sep 03 '17 at 11:10
  • A good answer, but slightly misleading. Reading your answer makes it seem like you are recommending raw SHA as method to hash passwords, which I assume is not the case, as raw SHA, salted or not, is not good for hashing passwords. – Luke Joshua Park Sep 04 '17 at 04:16
  • @LukePark Perhaps I should have made more clear that in fact I recommend scrypt. That's the reason why I have mentioned "slower hashing functions" and "increasing iterations". Besides that, if the local floriculturist club consisting of 14 members and hosting their website in a shared environment for $1 / month really needs scrypt hashing for password storage could be subject of endless discussions (probably, they can't use scrypt even if they are willing because their CMS doesn't provide it). – Binarus Sep 04 '17 at 06:56
  • @Downvoter Why the downvote? Please let me learn from your divine wisdom ... – Binarus Sep 04 '17 at 06:58
  • Every login system, no exceptions, should use iterative hashing. Bcrypt and PBKDF2 are normally recommended over scrypt. Never ever should a single hash function be used, but your answer implies that using SHA2 is fine. I'd fix that. – Luke Joshua Park Sep 04 '17 at 07:08
  • I do not think that bcrypt or pbkdf2 are recommended over scrypt. For example, scrypt has specifically been designed not only to be slow, but also to consume much memory to make hardware implementations difficult. It has a disadvantage, though: It is by far not as long around as bcrypt and pbkdf2, meaning that it is not tested for a long time yet. On the other hand, to my best knowledge, no weakness has been detected so far. And yes, of course, you can adjust the computational cost for scrypt. Regarding SHA2, I eventually will try to make my answer more clear. – Binarus Sep 04 '17 at 13:01
  • @LukePark Updated answer as per your request. It should be clear now. – Binarus Sep 04 '17 at 14:28
  • - "You don't want to _encrypt_ stored passwords. You want to _hash_ them. This is very important!" - "OK, cool. Is there a standard function for that?" - "Why yes, the function is named _encrypt()_." – Timothy Booth Sep 23 '19 at 09:28
0

The reason simple hashes like md5 and sha1 are not very secure is because there are easy to crack with todays computing power, you should use hashing with salt. [Here is a great StackOverflow answer to your question] (Secure hash and salt for PHP passwords).

WordPress does not uses MD5 anymore, WordPress is using the PasswordHash function, here is more about what WordPress does.