<p>We are currently storing plain text passwords for a web app that we have.  </p>

<p>I keep advocating moving to a password hash but another developer said that this would be less secure -- more passwords could match the hash and a dictionary/hash attack would be faster.</p>

<p>Is there any truth to this argument?   </p>

[{'answer_id': 59030, 'author': 'DaveK', 'author_id': 4244, 'author_profile': 'https://Stackoverflow.com/users/4244', 'pm_score': 1, 'selected': False, 'text': "<p>I'm not a security expert but I have a feeling that if plain text were more secure, hashing wouldnt exist in the first place. </p>\n"}, {'answer_id': 59033, 'author': 'qbeuek', 'author_id': 5348, 'author_profile': 'https://Stackoverflow.com/users/5348', 'pm_score': 3, 'selected': False, 'text': '<p>There is absolutely no excuse to keeping plain text passwords on the web app. Use a standard hashing algorithm (SHA-1, not MD5!) with a salt value, so that rainbow attacks are impossible.</p>\n'}, {'answer_id': 59035, 'author': 'Joel Coehoorn', 'author_id': 3043, 'author_profile': 'https://Stackoverflow.com/users/3043', 'pm_score': 5, 'selected': True, 'text': "<p>Absolutely none.  But it doesn't matter.  I've posted a similar response before:</p>\n\n<p>It's unfortunate, but people, even programmers, are just too emotional to be easily be swayed by argument.  Once he's invested in his position (and, if you're posting here, he is) you're not likely to convince him with facts alone.  What you need to do is switch the burden of proof.  You need to get him out looking for data that he hopes will convince you, and in so doing learn the truth.  Unfortunately, he has the benefit of the status quo, so you've got a tough road there.</p>\n"}, {'answer_id': 59037, 'author': 'Michael Stum', 'author_id': 91, 'author_profile': 'https://Stackoverflow.com/users/91', 'pm_score': 2, 'selected': False, 'text': '<p>If you do not salt your Password, you\'re suspect to Rainbow Table attacks (precompiled Dictionaries that have valid inputs for a given hash)</p>\n\n<p>The other developer should stop talking about security if you\'re storing passwords in plaintext and start reading about security.</p>\n\n<p>Collisions are possible, but not a big problem for password apps usually (they are mainly a problem in areas where hashes are used as a way to verify the integrity of files).</p>\n\n<p>So: Salt your passwords (by adding the Salt to the right side of the password*) and use a good hashing algorhithm like SHA-1 or preferably SHA-256 or SHA-512.</p>\n\n<p>PS: A bit more detail about Hashes <a href="https://stackoverflow.com/questions/415/decode-email-address-from-gravatar-hash#738">here</a>.</p>\n\n<p>*i\'m a bit unsure whether or not the Salt should to to the beginning or to the end of the string. The problem is that if you have a collisions (two inputs with the same hash), adding the Salt to the "wrong" side will not change the resulting hash. In any way, you won\'t have big problems with Rainbow Tables, only with collisions</p>\n'}, {'answer_id': 59038, 'author': 'Peter Bernier', 'author_id': 6112, 'author_profile': 'https://Stackoverflow.com/users/6112', 'pm_score': 2, 'selected': False, 'text': "<p>I don't understand how your other developer things 'more passwords could match the hash'.</p>\n\n<p>There is argument to a 'hash attack would be faster', but only if you're not salting the passwords as they're hashed. Normally, hashing functions allow you to provide a salt which makes the use of known hash table a waste of time. </p>\n\n<p>Personally, I'd say 'no'. Based on the above, as well as the fact that if you do somehow get clear-text expose, a salted, hashed value is of little value to someone trying to get in. Hashing also provides the benefit of making all passwords 'look' the same length.</p>\n\n<p>ie, if hashing any string always results in a 20 character hash, then if you have only the hash to look at, you can't tell whether the original password was eight characters or sixteen for example.</p>\n"}, {'answer_id': 59042, 'author': 'Matthias Winkelmann', 'author_id': 4494, 'author_profile': 'https://Stackoverflow.com/users/4494', 'pm_score': 1, 'selected': False, 'text': '<p>In theory, yes. Passwords can be longer (more information) than a hash, so there is a possibility of hash collisions. However, most attacks are dictionary-based, and the probability of collisions is infinitely smaller than a successful direct match. </p>\n'}, {'answer_id': 59043, 'author': 'Stu Thompson', 'author_id': 2961, 'author_profile': 'https://Stackoverflow.com/users/2961', 'pm_score': 0, 'selected': False, 'text': "<blockquote>\n  <p>more passwords could match the hash and a dictionary/hash attack would be faster.</p>\n</blockquote>\n\n<p>Yes and no.  Use a modern hashing algorithm, like an SHA variant, and that argument gets very, very week.  Do you really need to be worried if that brute force attack is going to take only 352 years instead of 467 years?  (Anecdotal joke there.)  The value to be gained (not having the password stored in plain text on the system) far outstrips your colleague's concern.    </p>\n"}, {'answer_id': 59047, 'author': 'palehorse', 'author_id': 312, 'author_profile': 'https://Stackoverflow.com/users/312', 'pm_score': 3, 'selected': False, 'text': '<p>From <a href="http://en.wikipedia.org/wiki/Password" rel="noreferrer">Wikipedia</a></p>\n\n<blockquote>\n  <p>Some computer systems store user\n  passwords, against which to compare\n  user log on attempts, as cleartext. If\n  an attacker gains access to such an\n  internal password store, all passwords\n  and so all user accounts will be\n  compromised. If some users employ the\n  same password for accounts on\n  different systems, those will be\n  compromised as well.</p>\n  \n  <p>More secure systems store each\n  password in a cryptographically\n  protected form, so access to the\n  actual password will still be\n  difficult for a snooper who gains\n  internal access to the system, while\n  validation of user access attempts\n  remains possible.</p>\n  \n  <p>A common approache stores only a\n  "hashed" form of the plaintext\n  password. When a user types in a\n  password on such a system, the\n  password handling software runs\n  through a cryptographic hash\n  algorithm, and if the hash value\n  generated from the user\'s entry\n  matches the hash stored in the\n  password database, the user is\n  permitted access. The hash value is\n  created by applying a cryptographic\n  hash function to a string consisting\n  of the submitted password and,\n  usually, another value known as a\n  salt. The salt prevents attackers from\n  building a list of hash values for\n  common passwords. MD5 and SHA1 are\n  frequently used cryptographic hash\n  functions.</p>\n</blockquote>\n\n<p>There is much more that you can read on the subject on that page.  In my opinion, and in everything I\'ve read and worked with, hashing is a better scenario unless you use a very small (&lt; 256 bit) algorithm.</p>\n'}, {'answer_id': 59051, 'author': 'Matt Sheppard', 'author_id': 797, 'author_profile': 'https://Stackoverflow.com/users/797', 'pm_score': 2, 'selected': False, 'text': "<p>There is truth in that if you hash something, yes, there will be collisions so it would be possible for two different passwords to unlock the same account.</p>\n\n<p>From a practical standpoint though, that's a poor argument - A good hashing function (md5 or sha1 would be fine) can pretty much guarantee that for all meaningfully strings, especially short ones, there will be no collisions. Even if there were, having two passwords match for one account isn't a huge problem - If someone is in a position to randomly guess passwords fast enough that they are likely to be able to get in, you've got bigger problems.</p>\n\n<p>I would argue that storing the passwords in plain text represents a much greater security risk than hash collisions in the password matching.</p>\n"}, {'answer_id': 59054, 'author': 'Tim Howland', 'author_id': 4276, 'author_profile': 'https://Stackoverflow.com/users/4276', 'pm_score': 1, 'selected': False, 'text': '<p>It depends on what you\'re defending against. If it\'s an attacker pulling down your database (or tricking your application into displaying the database), then plaintext passwords are useless. There are many attacks that rely on convincing the application to disgorge it\'s private data- SQL injection, session hijack, etc. It\'s often better not to keep the data at all, but to keep the hashed version so bad guys can\'t easily use it.</p>\n\n<p>As your co-worker suggests, this can be trivially defeated by running the same hash algorithm against a dictionary and using rainbow tables to pull the info out. The usual solution is to use a secret salt plus additional user information to make the hashed results unique- something like:</p>\n\n<pre><code>String hashedPass=CryptUtils.MD5("alsdl;ksahglhkjfsdkjhkjhkfsdlsdf" + user.getCreateDate().toString() +  user.getPassword);\n</code></pre>\n\n<p>As long as your salt is secret, or your attacker doesn\'t know the precise creation date of the user\'s record, a dictionary attack will fail- even in the event that they are able to pull down the password field.</p>\n'}, {'answer_id': 59056, 'author': 'rpetrich', 'author_id': 4007, 'author_profile': 'https://Stackoverflow.com/users/4007', 'pm_score': 2, 'selected': False, 'text': "<p>I encountered this exact same issue in my workplace.  What I did to convince him that hashing was more secure was to write a SQL injection that returned the list of users and passwords from the public section of our site.  It was escalated right away as a major security issue :)</p>\n\n<p>To prevent against dictionary/hash attacks be sure to hash against a token that's unique to each user and static (username/join date/userguid works well)</p>\n"}, {'answer_id': 59127, 'author': 'Graeme Perrow', 'author_id': 1821, 'author_profile': 'https://Stackoverflow.com/users/1821', 'pm_score': 1, 'selected': False, 'text': '<p>Nothing is less secure than storing plain-text passwords. If you\'re using a decent hashing algorithm (at least SHA-256, but even SHA-1 is better than nothing) then yes, collisions are possible, but it doesn\'t matter because given a hash, it\'s impossible* to calculate what strings hash to it. If you hash the username WITH the password, then that possibility goes out the window as well. </p>\n\n<p>* - technically not impossible, but "computationally infeasible"</p>\n\n<p>If the username is "graeme" and the password is "stackoverflow", then create a string "graeme-stackoverflow-1234" where 1234 is a random number, then hash it and store "<em>hashoutput</em>1234" in the database. When it comes to validating a password, take the username, the supplied password and the number from the end of the stored value (the hash has a fixed length so you can always do this) and hash them together, and compare it with the hash part of the stored value.</p>\n'}, {'answer_id': 59265, 'author': 'Luk', 'author_id': 5789, 'author_profile': 'https://Stackoverflow.com/users/5789', 'pm_score': 2, 'selected': False, 'text': '<p>There is an old saying about programmers pretending to be cryptographers :)</p>\n\n<p>Jeff Atwood has a good post on the subject: <a href="http://www.codinghorror.com/blog/archives/000953.html" rel="nofollow noreferrer">You\'re Probably Storing Passwords Incorrectly</a></p>\n\n<p>To reply more extensively, I agree with all of the above, the hash makes it easier <em>in theory</em> to get the user\'s password since multiple passwords match the same hash. However,\nthis is much less likely to happen than someone getting access to your database.</p>\n'}, {'answer_id': 83961, 'author': 'Asgeir S. Nilsen', 'author_id': 16023, 'author_profile': 'https://Stackoverflow.com/users/16023', 'pm_score': 0, 'selected': False, 'text': '<p>Hope you forgive me for plugging a solution I wrote on this, using client side JavaScript to hash the password before it\'s transmitted: <a href="http://blog.asgeirnilsen.com/2005/11/password-authentication-without.html" rel="nofollow noreferrer">http://blog.asgeirnilsen.com/2005/11/password-authentication-without.html</a></p>\n'}]
['https://Stackoverflow.com/questions/59022', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5882/']