160

The current top-voted to this question states:

Another one that's not so much a security issue, although it is security-related, is complete and abject failure to grok the difference between hashing a password and encrypting it. Most commonly found in code where the programmer is trying to provide unsafe "Remind me of my password" functionality.

What exactly is this difference? I was always under the impression that hashing was a form of encryption. What is the unsafe functionality the poster is referring to?

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • Excellent summary of subject on StackExchange security blog: http://security.blogoverflow.com/2011/11/why-passwords-should-be-hashed/ – David J. Liszewski Feb 16 '14 at 03:25
  • A well-written article about why you should not simply hash you secrets/passwords. Instead use HMAC. http://benlog.com/articles/2008/06/19/dont-hash-secrets/ – Jay Kumar Dec 09 '11 at 15:22
  • @JayKumar: The article you linked is very misleading. It conflates password salts (which are expected to be visible to attackers) with MAC keys (which are expected to remain secret). David J. Liszewski's link provides a much more accurate description. – Rufflewind Jun 13 '16 at 12:52

9 Answers9

245

Hashing is a one way function (well, a mapping). It's irreversible, you apply the secure hash algorithm and you cannot get the original string back. The most you can do is to generate what's called "a collision", that is, finding a different string that provides the same hash. Cryptographically secure hash algorithms are designed to prevent the occurrence of collisions. You can attack a secure hash by the use of a rainbow table, which you can counteract by applying a salt to the hash before storing it.

Encrypting is a proper (two way) function. It's reversible, you can decrypt the mangled string to get original string if you have the key.

The unsafe functionality it's referring to is that if you encrypt the passwords, your application has the key stored somewhere and an attacker who gets access to your database (and/or code) can get the original passwords by getting both the key and the encrypted text, whereas with a hash it's impossible.

People usually say that if a cracker owns your database or your code he doesn't need a password, thus the difference is moot. This is naïve, because you still have the duty to protect your users' passwords, mainly because most of them do use the same password over and over again, exposing them to a greater risk by leaking their passwords.

numaroth
  • 1,295
  • 4
  • 25
  • 36
Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
  • 1
    To be clear, get the desired security with the hash, it must be a cryptographically secure hash algorithm with the specific property that not only the hash be non-reversable BUT ALSO computationally impractical to generate ANY other string that generates the same hash. – Tall Jeff Nov 28 '08 at 21:25
  • 12
    Yes and no... Hash collisions need to be hard to generate for the sake of your own application's security, but non-reversability is sufficient for avoiding password leakage. – Dave Sherohman Nov 28 '08 at 21:37
  • Dave: No it isn't. Here is a hash that isn't reversible : `f(n) = n % 2`. It also has a very high collision rate and is totally useless for crypto purposes. A lack of collisions is critical in a cryptographyically-secure hash. – Noon Silk Sep 08 '09 at 03:15
  • 5
    silky: and how exactly are you going to get the original password back from your lousy hash function? I suggest you reread Dave's comment – Vinko Vrsalovic Sep 08 '09 at 06:28
  • 1
    If anything, a hash function that has a large number of collisions is better for the security of the passwords, however it would obviously mean more passwords could be used to login to the account. – williamvicary Oct 03 '12 at 14:11
  • if a user gets access to the server, they can get access to the config files. That being the case, is it recommended against storing the salt in the config files (i.e. should the salt be hardcoded)? – n00b Nov 05 '14 at 18:59
  • 1
    @n00b salt's can't be hard coded because every hashed item should use a separate salt. The point of a salt is if both UserA and UserB uses password "1234" if you find out UserA's password you can't tell UserB used the same password because they had different salts. It is not security critical that a salts is kept secret, most implementations just concatenate the salt on to the front or the back of the binary blob that represents the hash. – Scott Chamberlain May 31 '16 at 21:42
  • @ScottChamberlain, How is it known which salt was used to generate the hash of a user's password (i.e. the hash stored in /etc/shadow)? A successful authentication seems to require that we know which salt was used so we can hash a user's input so we may arrive at the same hash – sherrellbc Jul 06 '16 at 16:04
  • 1
    @sherrellbc Usually the salt is prepended or appended on to the hash. Specifically in `/etc/shadow` the data between the 2nd and 3rd `$` is the salt that was used. See [this page](http://www.aychedee.com/2012/03/14/etc_shadow-password-hash-formats/) for a full breakdown of how `/etc/shadow` stores it's hash and salt. – Scott Chamberlain Jul 06 '16 at 16:08
  • @VinkoVrsalovic would using independent keys for each encrypted password do anything to mitigate the risk (increase the complexity required by a hacker's machine) of the two-way nature of encryption? – Thomas Mar 09 '18 at 00:30
  • If a hacker owns your database, that guy will try to make sense out of the data that is not encrypted nor hashed in the first place. Starting a social engineering campaign by exploiting readable customer data is much easier and giving quicker results. A hacker must be very determined, patient and wealthy to use heavy computing power to find your key. Encryption surely comes with this risk the worst nightmare, but the flexibility of moving to more secure vaults, upgrading to more secure encryption algorithms, retroactively check if password policies are effective, can outweigh hashing. – Shrimpy Jul 01 '20 at 10:02
  • The question was about comparing encryption and hashing - social engineering does not enter in the picture of the answer at all, as it can be used whether you encrypt or hash your passwords. And about finding the key, it all depends on where are you storing it and how are you disposing of the key in memory after its use. I'd argue that it's much easier to have a well secured hashing setup - which can also be upgraded when better algorithms appear - than a well secured encryption setup. – Vinko Vrsalovic Jul 01 '20 at 10:20
  • @Thomas I don't think so. You still have to have some way to map each user's password to their key in the code in order to validate their password. You'd increase a bit the complexity of the attacker that now has to find all the keys and which key corresponds to which user. But all that will still be in the database and the code. And then, to what end? Just to avoid using hashes? For what reason would you prefer doing that? – Vinko Vrsalovic Mar 31 '22 at 10:53
37

Hashing is a one-way function, meaning that once you hash a password it is very difficult to get the original password back from the hash. Encryption is a two-way function, where it's much easier to get the original text back from the encrypted text.

Plain hashing is easily defeated using a dictionary attack, where an attacker just pre-hashes every word in a dictionary (or every combination of characters up to a certain length), then uses this new dictionary to look up hashed passwords. Using a unique random salt for each hashed password stored makes it much more difficult for an attacker to use this method. They would basically need to create a new unique dictionary for every salt value that you use, slowing down their attack terribly.

It's unsafe to store passwords using an encryption algorithm because if it's easier for the user or the administrator to get the original password back from the encrypted text, it's also easier for an attacker to do the same.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
14

Encrypted vs Hashed Passwords

As shown in the above image, if the password is encrypted it is always a hidden secret where someone can extract the plain text password. However when password is hashed, you are relaxed as there is hardly any method of recovering the password from the hash value.


Extracted from Encrypted vs Hashed Passwords - Which is better?

Is encryption good?

Plain text passwords can be encrypted using symmetric encryption algorithms like DES, AES or with any other algorithms and be stored inside the database. At the authentication (confirming the identity with user name and password), application will decrypt the encrypted password stored in database and compare with user provided password for equality. In this type of an password handling approach, even if someone get access to database tables the passwords will not be simply reusable. However there is a bad news in this approach as well. If somehow someone obtain the cryptographic algorithm along with the key used by your application, he/she will be able to view all the user passwords stored in your database by decryption. "This is the best option I got", a software developer may scream, but is there a better way?

Cryptographic hash function (one-way-only)

Yes there is, may be you have missed the point here. Did you notice that there is no requirement to decrypt and compare? If there is one-way-only conversion approach where the password can be converted into some converted-word, but the reverse operation (generation of password from converted-word) is impossible. Now even if someone gets access to the database, there is no way that the passwords be reproduced or extracted using the converted-words. In this approach, there will be hardly anyway that some could know your users' top secret passwords; and this will protect the users using the same password across multiple applications. What algorithms can be used for this approach?

lkamal
  • 3,788
  • 1
  • 20
  • 34
  • 1
    Okay, but when you log in to a service, your password is sent in plaintext/encrypted, because if it's sent as a hash to the server to be compared. a hacker could if they know the hash, just send the hash to the server to login. This is why passwords for comparison need to be sent encrypted to the server, where they are decrypted and hashed. This is safe right? As long as the passwords are never stored in unhashed form for long term and all occurences of encrypted/plaintext passwords are erased from any memory when no longer needed? – AgentM Apr 14 '19 at 09:23
8

I've always thought that Encryption can be converted both ways, in a way that the end value can bring you to original value and with Hashing you'll not be able to revert from the end result to the original value.

CheGueVerra
  • 7,849
  • 4
  • 37
  • 49
8

Hashing algorithms are usually cryptographic in nature, but the principal difference is that encryption is reversible through decryption, and hashing is not.

An encryption function typically takes input and produces encrypted output that is the same, or slightly larger size.

A hashing function takes input and produces a typically smaller output, typically of a fixed size as well.

While it isn't possible to take a hashed result and "dehash" it to get back the original input, you can typically brute-force your way to something that produces the same hash.

In other words, if a authentication scheme takes a password, hashes it, and compares it to a hashed version of the requires password, it might not be required that you actually know the original password, only its hash, and you can brute-force your way to something that will match, even if it's a different password.

Hashing functions are typically created to minimize the chance of collisions and make it hard to just calculate something that will produce the same hash as something else.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
6

Hashing:

It is a one-way algorithm and once hashed can not rollback and this is its sweet point against encryption.

Encryption

If we perform encryption, there will a key to do this. If this key will be leaked all of your passwords could be decrypted easily.

On the other hand, even if your database will be hacked or your server admin took data from DB and you used hashed passwords, the hacker will not able to break these hashed passwords. This would actually practically impossible if we use hashing with proper salt and additional security with PBKDF2.

If you want to take a look at how should you write your hash functions, you can visit here.

There are many algorithms to perform hashing.

  1. MD5 - Uses the Message Digest Algorithm 5 (MD5) hash function. The output hash is 128 bits in length. The MD5 algorithm was designed by Ron Rivest in the early 1990s and is not a preferred option today.

  2. SHA1 - Uses Security Hash Algorithm (SHA1) hash published in 1995. The output hash is 160 bits in length. Although most widely used, this is not a preferred option today.

  3. HMACSHA256, HMACSHA384, HMACSHA512 - Use the functions SHA-256, SHA-384, and SHA-512 of the SHA-2 family. SHA-2 was published in 2001. The output hash lengths are 256, 384, and 512 bits, respectively,as the hash functions’ names indicate.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Rahul Garg
  • 4,069
  • 1
  • 34
  • 31
5

Ideally you should do both.

First Hash the pass password for the one way security. Use a salt for extra security.

Then encrypt the hash to defend against dictionary attacks if your database of password hashes is compromised.

LogicMagic
  • 321
  • 3
  • 8
  • 3
    Encrypt it with what? If they pwned you so hard that they got to the database with all your user's passwords (hashed, encrypted or otherwise), wouldn't they be able to find the key to decrypt them? – Luc Oct 24 '12 at 18:43
  • 6
    This shoudn't be downvoted. It is a possibility which shouldn't be ruled out that easy, that the database is compromised while the application isn't. Therefore encrypting the hash is an extra layer of security. – Arie Apr 16 '15 at 19:58
  • 2
    @Luc I disagree with you, my previous self. I've seen too many SQL-injections that did not compromise the application code (or configuration files) and I am now of the opinion that **adding** a secret is helpful, be it in the form of encryption or in the form of a pepper, but it must **not replace** hashing. For a more complete answer, see here: https://security.stackexchange.com/a/31846/10863 – Luc Oct 13 '18 at 12:40
1

As correct as the other answers may be, in the context that the quote was in, hashing is a tool that may be used in securing information, encryption is a process that takes information and makes it very difficult for unauthorized people to read/use.

Peter Coulton
  • 54,789
  • 12
  • 54
  • 72
-10

Here's one reason you may want to use one over the other - password retrieval.

If you only store a hash of a user's password, you can't offer a 'forgotten password' feature.

Philtron
  • 43
  • 4
  • 18
    You obviously did not read the accepted answer well enough. Read carefully: You're _not_ supposed to offer a password **retrieval** feature. You're _supposed_ to offer a password **reset** feature. I have administered many websites for years, including vBulletin, phpBB, e107, IPB, blogspot, and even my own custom-built CMS. As an administrator you NEVER EVER need to have someone's pre-hashed password. You just don't. And you shouldn't have it either. If you don't agree with what I'm saying, let me assure you: you're wrong. – Lakey Jan 08 '13 at 03:05
  • 3
    Sorry about being WAY too angry. I just see too many websites store passwords in plain text and it frustrates me. As a side note: some security-minded websites like to make users change their passwords periodically. They want to ensure the person doesn't change his password from "Password1" to "Password2". So they retain the plain-text password in order to do these comparisons at a later date. That is not good practice. What they need to do, in that case, is perform analysis on the password FIRST, making a bunch of similar passwords -- hash each one -- and only store the _hashes_. – Lakey Jan 10 '13 at 19:50
  • 7
    No problem, it made me go back and re-read the question and also do further research, so all is not lost :-) I'm not sure what I was thinking when I wrote that answer. cheers – Philtron Jan 28 '13 at 14:13