And store the password encrypted...



  • I have been helping a guy with a project.  Originally I wasn't involved, but when it was six months late on a three month project, I got called in to do the other half which hadn't even been started.  I still remember the sick feeling in the pit of my stomach when the developer told me "all fields are varchar for simplicity".

     There's a database of users, who can log in.  Now, we all know that you store the password encrypted, right?  Perfect, it's stored as MD5.  Here's the three relevant fields in the database:

     name VARCHAR,

    password VARCHAR,

    password_md5 VARCHAR,

     ... and yes, the password field holds the plaintext password.

    Amazingly, the MD5 password is even calculated using a salt key. It's the MD5 hash of salt + name + password.  The salt is the name of the company the project is for.  Well, no.  It's a misspelling of the name, with two typos out of six letters.  Now, I'd have thought this might be intentional, except that two of the states a transaction can be in are CANCELED and CANCELLED_TX.

    The whole thing is like this.  Several megabytes of code.



  •  So, what's the problem?



  •  TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.



  • I know about a certain web-based app that not only stores passwords in plaintext, the login records also store the plaintext password in every log entry. Nice!

    I had to do some improvements on its functionality, but I was not allowed to change the "security", as it broke a lot of stuff if I modified it to "secure MD5". I would've gone for SSHA, but even trying to get them to use MD5 was useless.



  • @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

    Salted MD5 is still a perfectly secure way of hashing passwords. The weaknesses in MD5 are related to collision resistance; breaking hashed passwords is a first preimage attack, a totally different thing.



  • @Carnildo said:

    Salted MD5 is still a perfectly secure way of hashing passwords. The weaknesses in MD5 are related to collision resistance; breaking hashed passwords is a first preimage attack, a totally different thing.

    Given the history of MD5 (and hash algos in general) it is incredibly foolish to suggest that people continue using them.  Remember, the password systems being implemented by people today will often be used for 5 or more years: to suggest MD5 is ridiculous.  I understand that most of the effort has only been focused on collisions, but that means the algorithm itself is not cryptographically strong.  It's only a matter of time before more weaknesses are uncovered.

     

    Also, breaking MD5 is not nearly as difficult as you imply.  For one, MD5 is a very fast, efficient hash algorithm which is a bad thing.  The faster the algorithm, the easier it is to brute force.  What's more, MD5 cracking is extremely parallelizable.  With a decent number of users it's almost guaranteed one of their passwords would be found in a 50k dictionary of common passwords.  Even with a random 32-bit salt, a fairly effective rainbow table could be constructed from this dictionary.  Basing the security of your users on something as rickety as MD5 in the year 2008 is simply unbelievable.



  • @morbiuswilters said:

    TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.
    Wait, what?

    Enlighten me, please.

    Edit: time lapsed. Never mind. 



  • @morbiuswilters said:

    With a decent number of users it's almost guaranteed one of their passwords would be found in a 50k dictionary of common passwords.  Even with a random 32-bit salt, a fairly effective rainbow table could be constructed from this dictionary.

    What kind of attack are you conceptualizing? A dictionary attack does not require access to the hashed passwords, and is equally effective against any hashing method (or no hashing at all). A rainbow attack, on the other hand, requires access to the hashed passwords.

    And unless you know the salt, how do you propose to build a useful rainbow table for a random 32-bit salted hash? The best I can think of is to extend common passwords with random salt, generate a rainbow table, and hope you get a hit. But you're forced to generate a far, far bigger rainbow table. I don't know that I'd classify this as "fairly effective", but it's only a matter of time before it's feasible, of course.



  • @bstorer said:

    And unless you know the salt
    I'm reminded of another WTF from my last comany.  I posted this little bit about them the last time we were talking about salty hash browns.  Now I recall that when [the other developer] redesigned the database/app, he created a different salt for each user.  Then, he put the salt for each password in the same row as said password. The field was conveniently called 'salt.'

    so, WTF or not?



  • @morbiuswilters said:

    [rants against MD5]

    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.



  • @belgariontheking said:

    he created a different salt for each user.  Then, he put the salt for each password in the same row as said password. The field was conveniently called 'salt.'

    so, WTF or not?

    It's a fairly common practice, but not a best practice. The system should use different salts for each user, because it severely hampers rainbow tables and prevents duplicate passwords from having the same hash, so if one is broken, both aren't. But as I mentioned above, rainbow tables have to work against the hash. If you have the hash, it's most likely because you have the password table. Thus you'd have the salts, too. But that doesn't really make cracking many passwords much easier.



  • @derula said:

    @morbiuswilters said:
    [rants against MD5]
    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.
    Well, SHA-1 is pretty well broken now. I'm hesitant to suggest SHA-2 because it's a similar algorithm, so even though it's currently considered secure, it seems likely to me that it's only a matter of time until somebody finds an attack for it, too. How about Whirlpool? It's fairly standard, and to my knowledge has no known weaknesses.



  • @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

     

    ...not to mention using a hard-coded "salt".  Gotta love the fools who think they understand enough about security to create their own because they read a Jeff Atwood post.



  • @derula said:

    So, what do you suggest? Don't mean to prove you wrong, just interested in how you can / we all should do better.
     

    bcrypt.  There's an implementation available for almost every modern language/framework.



  • @bstorer said:

    A dictionary attack does not require access to the hashed passwords, and is equally effective against any hashing method (or no hashing at all).

    A dictionary attack doesn't imply using a dictionary against the login API.  Hopefully the API is intelligent enough to limit the speed and number of attacks anyway.  What we are worried about is someone getting ahold of the password database and using it to crack user passwords.  If it's at the point where someone has access to your password DB and the algo you used to store the passwords, your service is pretty much compromised.  The real reason to scramble passwords is because most users will use the same password for multiple services.  This means that as the developer of an app you have an obligation to protect the passwords the best you can so a malicious attack cannot get the plaintext password and use it to access their bank account or some other highly-privileged system.

     

    @bstorer said:

    The best I can think of is to extend common passwords with random salt, generate a rainbow table, and hope you get a hit.

    That's what I was implying.

     

    @bstorer said:

    But you're forced to generate a far, far bigger rainbow table.

    Not necessarily.  You probably know that rainbow tables can be built to conserve space at the cost of processor time or vice-versa.  A fairly sparse rainbow table could store common passwords with every random 32-bit salt.  Obviously this isn't something you would do for shits and giggles, but we're not worried about script kiddies here but competent hackers.  We're assuming they have access to a large amount of storage (a few TB) as well as a botnet or some other form of distributed parallel processing.  The real problem comes down to the fact that MD5 is a very fast algo.  It was designed to be fast and when it comes to hashing passwords this is the opposite of what you want -- you want the algo to take as long as is reasonably possible to hash the data.  Also keep in mind that any password system implemented today will probably be used for 5 years at a minimum.  Hackers are using increasingly sophisticated methods to crack passwords, including harnessing the power of GPUs and processors like Cell.

     

    The fact is, MD5 is toast.  Defending it is pointless now.  It's overkill for CRC checks, it's not cryptographically strong enough for message digests, it's not optimal enough for in-memory hashtables, it's too fast for password hashing and it doesn't generate results that are as evenly distributed as other algos for use in a distributed hashtable.  There's no reason to suggest anyone use it now.



  • @bstorer said:

    It's a fairly common practice, but not a best practice.

    Not sure what you mean here.  Salts sould always be randomly generated, per-user and should be stored with the password DB.  That is best practice.



  • @morbiuswilters said:

    @bstorer said:

    It's a fairly common practice, but not a best practice.

    Not sure what you mean here.  Salts sould always be randomly generated, per-user and should be stored with the password DB.  That is best practice.

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.



  • @bstorer said:

    Well, SHA-1 is pretty well broken now. I'm hesitant to suggest SHA-2 because it's a similar algorithm, so even though it's currently considered secure, it seems likely to me that it's only a matter of time until somebody finds an attack for it, too. How about Whirlpool? It's fairly standard, and to my knowledge has no known weaknesses.

    It's pretty well accepted at this point that all hashing functions will ultimately succumb to collision attacks.  However, collision attacks aren't really what we are worried about when it comes to password hashing.  We just want a function that cannot be reversed and that takes a lot of cycles to calculate.  In this case, SHA-1 is better on both accounts than MD5, but it's still not secure enough on its own.  bcrypt is generally going to be your best bet, but second to that would be SHA-1 or SHA-2 with a long, random and per-user salt and some method of key stretching that increases the number of cycles it takes to generate a hash.



  • @bstorer said:

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.

    Why would that matter?  The only thing that would protect you against was if the attacker could get the password table but not the salt table.  This is just another form of security through obscurity and it should be avoided as it tends to produce an unwarranted sense of security.  It's the equivalent of having a 9-inch thick solid steel door with massive locks and then propping a chair up in front of it to make it slightly harder to push open.  In that situation, the chair seems ridiculous and anyone can see that.  The problem is, things like "put the salts in another table" aren't instantly and obviously ridiculous so people become deceived into thinking they are safer than they are.  It's not best practice because wasting the time separating the salts from the passwords means you have less time to focus on measures that actually increase the security of your app (building a stronger door).  When it comes to cryptographic security, it is of the utmost importance for people to avoid doing what "feels safe" and to focus on proven, documented methods that are guaranteed mathematically to increase security.



  • @morbiuswilters said:

    @bstorer said:

    No, storing the salts away from the passwords would be best practice, but as I explained above, it's not really a huge difference.

    Why would that matter?  The only thing that would protect you against was if the attacker could get the password table but not the salt table.  

     

    You're absolutely right, and that's why people should store the salts away from the passwords.

    I once worked on a large (1m+ users) website which did this. The salts are stored on the webservers that sit on the DMZ; the passwords are stored in the databases that sit on an internal network. As a developer I had access to the DMZ network but absolutely no access to the network containing the databases. The DBAs sat in a different building and had access to the databases but no access to the web servers. So no one person could get the salts AND the passwords; two people from across the network divide would have to collaborate... star-crossed lovers, maybe.



  • @morbiuswilters said:

    When it comes to cryptographic security, it is of the utmost importance for people to avoid doing what "feels safe" and to focus on proven, documented methods that are guaranteed mathematically to increase security.

    I was reminded of this last night when I was re-reading Richard Feynman's book "Surely Your Joking Mr Feynman?". In one of the essays on life in the Manhattan project he reminisced about an army officer who decided that his secrets were more important than anyone else in the project, so rather than use the standard locked filing cabinet he insisted on a huge full blown safe. The safe required a team of men to drag it into the building using all sorts of devices.

    At the end of the project they discovered that he had left the combination set to the factory default.



  • @morbiuswilters said:

    It's overkill for CRC checks
     

    And we already use too many redundant cyclic redundancy check checks.



  • @morbiuswilters said:

    The problem is, things like "put the salts in another table" aren't instantly and obviously ridiculous so people become deceived into thinking they are safer than they are.
    I didn't say "store them in a different table", I said to store them separately. Surely you see the difference in the two, don't you?@morbiuswilters said:
    It's not best practice because wasting the time separating the salts from the passwords
    An incredibly time-intensive venture, I'm sure. @morbiuswilters said:
    means you have less time to focus on measures that actually increase the security of your app (building a stronger door).
    Then in that case, the only important thing is protecting the password table from being compromised in the first place. Once an attacker has the database, the strongest encryption in the world will only protect it for so long.



  • @gutch said:

    I once worked on a large (1m+ users) website which did this. The salts are stored on the webservers that sit on the DMZ; the passwords are stored in the databases that sit on an internal network. As a developer I had access to the DMZ network but absolutely no access to the network containing the databases. The DBAs sat in a different building and had access to the databases but no access to the web servers. So no one person could get the salts AND the passwords; two people from across the network divide would have to collaborate...

    What a convoluted, useless setup.  For one, how were salts being stored on the webservers?  Were you running databases on these machines?  The real problem though is that you think this sort of separation is really all that useful.  Anyone with admin access to the webserver could just sniff the SQL traffic and see the hashed password.  What's more, they could probably just steal the unhashed passwords as they came in.  Additionally, I doubt the machines were actually physically separated -- they probably shared a DC.  In that case anyone with physical access could just pop the drives out of both machines and walk off with the passwords and the salts.  Seriously, whatever security you think hiding the salts gives you is usually not worth the effort.


    @gutch said:

    star-crossed lovers, maybe.

    I do not think this means what you think it means.



  • @morbiuswilters said:

    Anyone with admin access to the webserver could just sniff the SQL traffic and see the hashed password.  What's more, they could probably just steal the unhashed passwords as they came in.  Additionally, I doubt the machines were actually physically separated -- they probably shared a DC.  In that case anyone with physical access could just pop the drives out of both machines and walk off with the passwords and the salts.
    You could also find out the name of one of the users, find out their address, break into their house, and asked them for their password at gun-point. 



  • @bstorer said:

    I didn't say "store them in a different table", I said to store them separately. Surely you see the difference in the two, don't you?

    What are you trying to nitpick here?  I never said the two tables had to be in the same database or even the same planet.

     

    @bstorer said:

    An incredibly time-intensive venture, I'm sure.

    No, but it's not time well-spent.  What's more, it implies that you aren't using a well-proven crypto library but instead are implementing your own hashing and salting scheme.  This is very bad.

     

    @bstorer said:

    Then in that case, the only important thing is protecting the password table from being compromised in the first place. Once an attacker has the database, the strongest encryption in the world will only protect it for so long.

    Obviously we want to protect the password table from being compromised.  If the password table is stolen that means most of the system is already compromised.  However, that is not the point of hashing the passwords in the first place.  The goal is not to protect the password table or salt table or any of it.  The goal is that if someone has the passwords and the salts it should still take an enormous amount of time or significant advancements in cryptography to find the original password.  That is all.  It's a good bet that the strongest crypto today will probably be broken in 50 years, so even in the absense of massive computing power there is an upper bound to the amount of time the password will remain a secret.  The hope is that in 50 years nobody is using the same password they are today.

     

    Cryptography is about staying one step ahead of the people trying to crack your security.  The problem with "clever" schemes like storing the salts on one machine and the passwords on another is that they detract from the real focus.  The only thing that secures your data is the state of the art in cryptography.



  • @Zecc said:

    You could also find out the name of one of the users, find out their address, break into their house, and asked them for their password at gun-point.

    Precisely.  Crypto is just a small part of the security pie.  The whole point is to make the security of certain aspects of the system guaranteed so you can focus on securing other parts of the software.  Crypto forms a rigorously tested, mathematical base for security but there are plenty of things it is not meant to guard against.  The problem with storing the salts and passwords separately is that it is essentially adding an infinitesimal amount of security to the crypto.  If the base is no good all your safeguards are worthless.  If the base is good, your safeguards are such a puny improvement that they are not worth the time.  There are plenty of things that crypto cannot do, like keeping your users from being held at gun-point.  Really, the only thing it is good at is securing data.  And it's really fucking good at that.  Attempts to "help out" the crypto add a pitiful amount of protection at best.  At worst they detract from the other angles of security crypto cannot cover, they instill a false sense of security and there is a good chance you will fuck something up in the crypto implementation because you are messing around with the details instead of relying on it to do what it is supposed to do.  



  • @morbiuswilters said:

    What's more, it implies that you aren't using a well-proven crypto library but instead are implementing your own hashing and salting scheme.  This is very bad.
    How does it imply that at all? What does the storage method for the data have to do in the slightest with what crypto library is in use? Are you suggesting that I can't use Twofish if I have the data stored in separate locations?
    @morbiuswilters said:
    The goal is that if someone has the passwords and the salts it should still take an enormous amount of time or significant advancements in cryptography to find the original password.  That is all.
    I'm well aware of that. But cracking said hashes without the salt is slower than cracking them with the salt. Hence, it's better to store the salt away from the passwords, because losing one doesn't necessarily mean losing both.
    @morbiuswilters said:
    Cryptography is about staying one step ahead of the people trying to crack your security.
    No it isn't. Cryptography is about making the cost necessary to recover your data exceed its value.



  • @bstorer said:

    Cryptography is about making the cost necessary to recover your data exceed its value.

    Programmers are notorious for underestimating the value of a password.  Like it or not, most people use the same password or set of passwords everywhere.  And if an attacker has access to passwords, he probably also has access to e-mail addresses, and there's tremendous value in even a few hundred of those - chances are very high that at least one of those can get you into somebody's e-banking.

    When discussing security, you have to think like a crook.  The vast majority of thieves and pickpockets and con artists aren't trying to rob banks or steal classified government documents; they're on the street, looking for rubes with their wallets sticking out of their back pockets or carrying purses with long flimsy straps.  Or they're smashing car windows, or house windows belonging to people whom they know are on vacation.  The actual value of whatever's in there is almost immaterial; criminals want easy targets because the law of averages is on their side and they know they will eventually hit pay dirt.

    You think crackers want to waste their lifetimes trying to crack Gmail?  They trawl the entire web looking for sites that have weak security, ones that might be susceptible to some well-known exploit or have a backdoor installed, and they go to town on them, assuming that they will eventually uncover something of value.  And the letters "MD5" or "SHA" just scream "weak custom security".  They're nearly as bad as plaintext.

    Why anyone would waste time trying to segregate MD5 salts from hashes when it would take all of 10 minutes to replace the whole thing with a free bcrypt implementation is beyond my comprehension.  I can only surmise that these people are so fascinated by their own inventions that they lose any objectivity in the matter.



  • @morbiuswilters said:

    ... you want the algo to take as long as is reasonably possible to hash the data....
     

    No problem!  for (unsigned int i = 0; i <= 4294967295; i++ ) sleep(i);

    /joking ...



  • @Aaron said:

    And the letters "MD5" or "SHA" just scream "weak custom security".
    No they don't. Nothing about MD5 or SHA scream "custom" in the least.@Aaron said:
    They're nearly as bad as plaintext.
    This is a blatant falsehood. They're far less secure than they were designed to be, but it still takes ample computer power and time to generate a collision. Last I checked, the distributed computing project to generate an SHA-1 collision hadn't had any success yet. And no know attack is yet available for SHA-2. It's not like they're rot13. Also, note that I recommended avoiding them earlier in favor of Whirlpool.
    @Aaron said:
    Why anyone would waste time trying to segregate MD5 salts from hashes when it would take all of 10 minutes to replace the whole thing with a free bcrypt implementation is beyond my comprehension.
    Once again, I've never suggested using an MD5 hash, regardless of the salt. And if you want to be technical, you should be replacing it with Twofish, not bcrypt.



  • @bstorer said:

    No they don't. Nothing about MD5 or SHA scream "custom" in the least.

    Not necesarily, but the fact we are discussing it at all is pretty bad.  The fact is, there are plenty of good, existing implementations of this and trying to roll-your-own is just silly.  bcrypt is good, but MD5-based solutions can work as well if they have the right salt-generation and key stretching techniques.  The point is to use an existing solution rather than dreaming up your own.  Modern password-hashing schemes make no effort to separate the salts from the hashes.  This is because the creators realize that there is little point in doing so.

     

    @bstorer said:

    Also, note that I recommended avoiding them earlier in favor of Whirlpool.

    Generally not a good move.  If you are going to use a cryptographic hashing algo, it's best to go with a widely-tested one like SHA rather than a relatively unknown one like Whirlpool.  SHA may have its weaknesses, but we also know the NSA discovered flaws in SHA-0 awhile ago and urged people to move to the newer SHA algos.  I think it's safe to conclude that SHA will probably hold up for a few more years.  What's more, the weaknesses of SHA and MD5 have little to do with their suitability as password hashing schemes.  Seriously, you guys need to get this through your heads.  MD5 and SHA are not reversible and the collision attacks against them are of little use in finding the unhashed password.

     

    @bstorer said:

    And if you want to be technical, you should be replacing it with Twofish, not bcrypt.

    Where do you get this from?  bcrypt uses an expensive form of blowfish specifically meant for hashing passwords.  The fact that you suggest Twofish indicates you have a custom solution in mind.  Once again, this is a very bad idea.  There are several good password hashing libraries out there.  Use them.  Do not roll your own.  Do not waste time separating salts from the hashes.



  • @morbiuswilters said:

    bcrypt uses an expensive form of blowfish specifically meant for hashing passwords.  The fact that you suggest Twofish indicates you have a custom solution in mind.
    @Wikipedia(Twofish) said:
    Twofish is related to the earlier block cipher Blowfish
    30 seconds of my time



  • @Zecc said:

    @morbiuswilters said:

    bcrypt uses an expensive form of blowfish specifically meant for hashing passwords.  The fact that you suggest Twofish indicates you have a custom solution in mind.
    @Wikipedia(Twofish) said:
    Twofish is related to the earlier block cipher Blowfish
    30 seconds of my time

    What the fuck?  I know Twofish is based on Blowfish.  bcrypt is also based on Blowfish.  That doesn't mean bcrypt is based on Twofish.  bcrypt uses an algorithm that descends from the same ancestor as Twofish.  bcrypt's algorithm is specifically made to be expensive as possible.  It is custom-designed by crypto experts for the purpose of hashing passwords.  Twofish is not.  Do you understand yet?



  • Whoa, the Ultimate Cypher & Hash Showdown!!!

    However, I'm interested in having username/passwords on a database table to begin with! Isn't it more secure to actually have these on an LDAP server, resting on a server other than the one(s) hosting the DBMS and the application itself? LDAP servers (or at least, those I've used) use SSHA (SHA-1 or SHA-2, salted) for password storage, and give you the added benefit of receiving the plaintext password and doing the hash verification by itself, so you can have the userPassword field locked out to anyone except the LDAP admin or the actual user. Meanwhile, DB tables require the app to do the actual hashing, so the hash has to be available outside the DB.

    Of course, for the solution to be really secure, you should use ldaps:// or IPSec, otherwise anyone sniffing the server network would sniff up the nice, juicy plaintext passwords.



  • @danixdefcon5 said:

    Isn't it more secure to actually have these on an LDAP server, resting on a server other than the one(s) hosting the DBMS and the application itself?

    No it isn't.  You haven't been listening.  Trying to hide the passwords or restrict access to the LDAP admin does not make the passwords safer.  The integrity of the hashes is only guaranteed by the crypto/hashing algo used.  Nothing else matters.

     

    @danixdefcon5 said:

    Of course, for the solution to be really secure, you should use ldaps:// or IPSec, otherwise anyone sniffing the server network would sniff up the nice, juicy plaintext passwords.

    If someone can sniff your server network you are already fucked.  This means they have physical access to the machines or have compromised one of the hosts and can do anything they want.  They don't need to sniff the network.  Using encryption on an internal, server-only network is pretty much pointless.  If your servers aren't on their own physically-secured network then your first priority should be buying a switch, not screwing around with encryption.



  • @bstorer said:

    This is a blatant falsehood. They're far less secure than they were designed to be, but it still takes ample computer power and time to generate a collision. Last I checked, the distributed computing project to generate an SHA-1 collision hadn't had any success yet.

    Ah, but there's the rub - when you've got your hands on a password database, you're no longer attempting a collision with one hash, you're attempting it with any of the hundreds or thousands or millions of hashes in the database.  That's a major difference when you're talking about only 2^35 computations, which is what SHA-1 has been busted down to by now.  You're also ignoring pure hardware-based implementations; computing power is expensive but SHA or MD5 can also be generated on a $2 FPGA.

    Also, note that I recommended avoiding them earlier in favor of Whirlpool.

    Except that whirlpool can actually be done faster.  See here.

    And if you want to be technical, you should be replacing it with Twofish, not bcrypt.

    No.  You shouldn't.  bcrypt is optimized for computationally expensive hashing, Twofish is not.

     

    Even having said all this - even if you could reasonable assume that nobody would ever be able to crack your MD5 or SHA-hashed database without an NSA lab and several years to do it - why would you knowingly use something that's merely "good enough" when you already have tools at your disposal that are better and require no additional effort or resources to use?



  • @danixdefcon5 said:

    Of course, for the solution to be really secure, you should use ldaps:// or IPSec, otherwise anyone sniffing the server network would sniff up the nice, juicy plaintext passwords.

     

    That is transport-level security.  For systems where that isn't an option (i.e. almost all of them), if you're truly concerned about eavesdropping then you use Kerberos, SRP, or some similar key-exchange system.



  • @Aaron said:

    Ah, but there's the rub - when you've got your hands on a password database, you're no longer attempting a collision with one hash, you're attempting it with any of the hundreds or thousands or millions of hashes in the database.  That's a major difference when you're talking about only 2^35 computations, which is what SHA-1 has been busted down to by now.

    The problem is that you aren't looking for a collision so this is completely irrelevent.  Collisions destroy the ability of a hashing algo to be used for data integrity.  That's because someone can replace trusted data with untrusted data that hashes the same.  With passwords, you aren't trying to find any password that hashes the same but the exact password that was used.  This means that all of the collision tricks of padding the untrusted data with arbitrary "junk" bytes to end up with the same hash are useless.  Additionally, I seem to recall that all of the collision methods require access to the middle-state of the SHA or MD5 transformation.  This can only be achieved if you know the original plaintext (which you would in the case of data integrity).  Since you don't have the unhashed password you can't recreate the middle phases of the algorithm and manipulate the untrusted data to create a collision.  Thusly the collision attacks aren't all that big of a deal for password hashing.  A bigger deal is the speed of MD5 and SHA, both of which are very fast.  Of course, if given the choice between MD5 or SHA you should still go with SHA simply because it has fewer known cryptographic flaws.  Obviously something like bcrypt is your best bet, but there are suitable alternatives as well.  The important part is to never create your own password hashing scheme and instead stick with a tested, proven and reliable implementation.



  • @Aaron said:

    That is transport-level security.  For systems where that isn't an option (i.e. almost all of them), if you're truly concerned about eavesdropping then you use Kerberos, SRP, or some similar key-exchange system.

    Read my point above.  TLS and the like are pretty much useless if your private server network can be sniffed. 



  • @morbiuswilters said:

    @danixdefcon5 said:

    Isn't it more secure to actually have these on an LDAP server, resting on a server other than the one(s) hosting the DBMS and the application itself?

    No it isn't.  You haven't been listening.  Trying to hide the passwords or restrict access to the LDAP admin does not make the passwords safer.  The integrity of the hashes is only guaranteed by the crypto/hashing algo used.  Nothing else matters.

    I have been listening. Of course the password must be stored with a strong one-way hash/cipher in the database. And I also know about something called RACF that uses the mainframe's tamper-proof cypher chips to store said passwords, and restricts access to said password. It isn't like the stuff is readily available even with MASTER access, so that's at least one case where your password would be pretty safe. Oh, and there is an LDAP/RACF compatibility plugin for IBM SecureWay/Tivoli Directory Services, so you get LDAP auth with RACF as backend.

    @morbiuswilters said:

    @danixdefcon5 said:

    Of course, for the solution to be really secure, you should use ldaps:// or IPSec, otherwise anyone sniffing the server network would sniff up the nice, juicy plaintext passwords.

    If someone can sniff your server network you are already fucked.  This means they have physical access to the machines or have compromised one of the hosts and can do anything they want.  They don't need to sniff the network.  Using encryption on an internal, server-only network is pretty much pointless.  If your servers aren't on their own physically-secured network then your first priority should be buying a switch, not screwing around with encryption.

    Not necessarily. Financial institutions tend to do this, because they run on the premise that nobody can be trusted, not even IT. Many scams in the banking business are perpetrated by insiders, so even the "secure" internal network isn't fully trusted. I've seen at least one IPSec setup because of this, and the only reason they didn't go for SSL was for performance issues. The LDAP and application server are on different networks, so it isn't like switching is going to solve the problem.

    Of course, you do have a point, as someone actually sniffing on the internal routers would be a bad sign, as it means something is FUBAR'd in your network security.



  • @danixdefcon5 said:

    And I also know about something called RACF that uses the mainframe's tamper-proof cypher chips to store said passwords, and restricts access to said password. It isn't like the stuff is readily available even with MASTER access, so that's at least one case where your password would be pretty safe. Oh, and there is an LDAP/RACF compatibility plugin for IBM SecureWay/Tivoli Directory Services, so you get LDAP auth with RACF as backend.

    You have jumped to specialized hardware now.  That's all well and good but it has nothing to do with LDAP.  Most people don't need specialized hardware and it is probably quite possible to retrieve the data if you were really inclined to do so.  There's also nothing preventing a RDBMS from accessing specialized hardware, either.  The point is that your statement about LDAP is wrong.  LDAP provides no more security for storing hashes than an RDBMS.  Stop trying to argue with this point, you're only going to make yourself look silly.

     

    @danixdefcon5 said:

    Financial institutions tend to do this, because they run on the premise that nobody can be trusted, not even IT. Many scams in the banking business are perpetrated by insiders, so even the "secure" internal network isn't fully trusted.

    Understandable, but it's still probably mistaken.  Guess what, at some point you have to trust people.  If I have physical access to the hardware I can find ways to get sensitive data off of the system and manipulate records.  There are methods to combat this but encrypting an internal network isn't one of them.

     

    @danixdefcon5 said:

    The LDAP and application server are on different networks, so it isn't like switching is going to solve the problem.

    Either they are on server networks or not.  If they are, switching, routing and restricting physical access are all that is needed.  If there are untrusted users on the networks, then the data should be encrypted.  However, servers should generally be isolated from clients by physically separate networks in all but the smallest shops.  Physical segregation of the servers is far safer than encryption, end of story.



  • @morbiuswilters said:

    Understandable, but it's still probably mistaken.  Guess what, at some point you have to trust people.  If I have physical access to the hardware I can find ways to get sensitive data off of the system and manipulate records.  There are methods to combat this but encrypting an internal network isn't one of them.

    Sure you have to trust people, but sensible security means only entrusting people with the minimum access they need to do their job. Why would a company let just anyone have physical access to hardware? It's relatively cheap and easy to lock your hardware away from most staff. By doing so you've massively reduced your attack surface because 99% of your staff can't physically access the systems. Then your password hashing just has to stand up to the few who do have access.

    The company where I used to work seem to have an extra layer that I call 'Security by Incompentence': all hardware access was done by a team of electrical engineers with no understanding of software. They wouldn't dare pressing F1 during a reboot unless a developer was on the phone talking them through how to do it.

     

    By the way, with regard to

    @morbiuswilters said:

    For one, how were salts being stored on the webservers?  Were you running databases on these machines?

    This was an enterprise app, so the answer is obvious: store the salts in XML!
    Actually it seems a reasonable solution to me. The hashing is done in the business layer code on the application servers, so the salts (only a few hundred, not one per password) are stored locally in XML for quick lookup. So it's (very) slightly less database traffic than storing the salts in the databases, and the DBAs never have access to the salts.



  • @gutch said:

    Sure you have to trust people, but sensible security means only entrusting people with the minimum access they need to do their job. Why would a company let just anyone have physical access to hardware? It's relatively cheap and easy to lock your hardware away from most staff. By doing so you've massively reduced your attack surface because 99% of your staff can't physically access the systems.

    Where did I say that physical access shouldn't be restricted?  Did you even read the words I wrote?  I was arguing that encrypting communications between servers on an internal server network is useless because anyone can sniff the traffic already has physical access to the machines.  Once someone has physical access, there's not much you can stop them from doing.  That's why physical access should be so restricted.

     

    @gutch said:

    Then your password hashing just has to stand up to the few who do have access.

    No!  Bad!  This is not why you hash passwords.  If someone has physical access to the machine or even root access they can just grab the passwords as they come in unhashed.  Hashing the passwords is to protect against someone obtaining the entire password database.

     

    @gutch said:

    Actually it seems a reasonable solution to me. The hashing is done in the business layer code on the application servers, so the salts (only a few hundred, not one per password) are stored locally in XML for quick lookup.

    Why would you have "only a few hundred"?  Fuck it, nobody is paying any attention, are they?  Each password needs its own randomly generated salt.  However, you obviously don't know enough about crypto to be messing with this kind of thing.  Use a fucking library.  Oh, and storing the salts on the web server is great until you have more than one.  Fail.

     

    @gutch said:

    So it's (very) slightly less database traffic than storing the salts in the databases...

    If internal network traffic to the DB server is that big of a concern to you, then wow.  Just wow.

     

    @gutch said:

    ...and the DBAs never have access to the salts.

    Which does not improve the security of the system.  It is NOT WORTH THE EFFORT.  Got it?  It's just security theater.  If you seriously think storing the salts separate from the hashes so two different teams cannot access both you have far bigger problems than crypto.  For one, you do not trust your people which means they should not be working for you.  Two, you completely disregard that anyone with physical access to both machines can just steal it all.  Finally, you are desperately hoping that hiding the salts is going to improve the security of your system.  It is not.  The only factor that should be taken into consideration is the strength of the password hashing system you are using.  Anything else pales in comparision and is a distraction.  This is why you need to use a proven library and stop dreaming up nonsense like this.



  • @gutch said:

    Then your password hashing just has to stand up to the few who do have access.

    @gutch said:
    Actually it seems a reasonable solution to me. The hashing is done in the business layer code on the application servers, so the salts (only a few hundred, not one per password) are stored locally in XML for quick lookup. So it's (very) slightly less database traffic than storing the salts in the databases, and the DBAs never have access to the salts.

    Okay, people. Let's get this all clear: my argument with morbiuswilters earlier was on extremely theoretical points, and I continued said argument with the belief that other readers would know better than to do those things. How terribly, terribly wrong I was. For the love of ammoQ, don't do anything I suggested unless you're well, well educated on cryptanalysis (and even then, have a very good reason). Use bcrypt, use 1 salt per user, store said salt in the database, and please, please, please do not try thinking on your own. A WTF is all fun and games until somebody's identity is stolen.



  •  @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

    I don't mean to nitpick, but if an attacker already has the plaintext password, from the database field described in the OP, "password," in addition to having the MD5-hashed password, from the field "password_md5," what difference would it make that the hash could eventually be broken. I mean if I have given up the plaintext password, how does using the "wrong" hash function make that even worse?

     



  • @dgvid said:

     @morbiuswilters said:

     TRWTF is using MD5 in this day and age.  Actually, using any hashing algo to store passwords.

    I don't mean to nitpick, but if an attacker already has the plaintext password, from the database field described in the OP, "password," in addition to having the MD5-hashed password, from the field "password_md5," what difference would it make that the hash could eventually be broken. I mean if I have given up the plaintext password, how does using the "wrong" hash function make that even worse?

    HAHAHAHAHAHA! True, it got lost in the cypher/digest war!!! But hey, there's a good point ... not only can the attacker get the plaintext password, he can prove the passwords are right by doing an md5check!!!



  • @danixdefcon5 said:

    True, it got lost in the cypher/digest war!!!
     

    My actual intent was to educate people on non-obvious aspects of password security (such as avoiding MD5).  I think I was able to lead the discussion in that direction. 



  • @morbiuswilters said:

    My actual intent was to educate people on non-obvious aspects of password security (such as avoiding MD5).  I think I was able to lead the discussion in that direction. 

    And it was a good one, too! You'd be amazed at the hoardes of web-developers that say that they store their passwords "encrypted with MD5".

    Or even worse, I know at least one that uses "base64 encryption".



  • @Aaron said:

    bcrypt.  There's an implementation available for almost every modern language/framework.


    If an application has a vulnerability that can be used to get the encrypted passwords, then that vulnerability can be probably also be used to get the key that was used to encrypt the passwords.

    If you get that key it will be easy to decrypt all the passwords.


Log in to reply