Almost correct password encryption



  • The method typically used for password encryption is to take a user's password, append a random set of characters to that password, and use a non-reversible hasing algorithm on that new set of data, and do it all over again with the same hash some number of times.

    Just found this in a php source file for one of our apps:

    private static function encrypt_password($password, $hashsalt){
            for($i=0;$i<self::$HASH_ITERATION;$i++){
                $encryptedpass = base64_encode(hash_hmac(self::$HASH_ALGO, $password . $hashsalt, self::$HASH_KEY, TRUE));// base 64 encode the raw binary data.
            }
            return $encryptedpass;
        }

    The salt is 10 characters randomly generated through sha1, and it would appear that the code iterates the password over and over some number of times.

     Well, yes, it does iterate $password over and over, but $password never changes. Which means it generates the same hash over and over.

    facepalm

     So, do we fix it in production and re-encrypt the passwords $HASH_ITERATION-1 times? Nah....

    inb4 trwtf is php

     



  • @annihilatorg said:

    inb4 trwtf is php
    Is that even legal in an OP?



  • @C-Octothorpe said:

    @annihilatorg said:

    inb4 trwtf is php
    Is that even legal in an OP?

    No. Foul. 10-year penalty.



  • TRWTF is rolling your own password hashing method.

    Other WTFs:

    • Using HMAC for password hashing. WTF?
    • Your class consts aren't really consts. They're just capitalized variables.
    • Base64 encoding the raw output instead of just using hex output.
    • "The salt is 10 characters randomly generated through sha1" WTF does this mean?


  • @morbiuswilters said:

    • your class consts aren't really consts. They're just capitalized variables.

    Yeah, but:

    @dhromed said:

    So no, case has no meaning, regardless of whether a language treats B and b as different.

    Any.. TRWTF is that they didn't use ROT-26 as an encryption method. Foolproof.



  • What is the purpose of iterating a number of times, and what is supposed to change?



  • @Cassidy said:

    @dhromed said:
    So no, case has no meaning, regardless of whether a language treats B and b as different.

    I'm not sure what that quote means. Context might help. Regardless, PHP has constants and variables which are distinct syntactical elements. self::$FOO means they are using a variable to store a constant value, which makes no sense.



  • @Sutherlands said:

    What is the purpose of iterating a number of times, and what is supposed to change?

    DO NOT DO THIS. NEVER ROLL YOUR OWN CRYPTO FUNCTIONS. USE bcrypt OR scrypt IF YOU NEED SECURE PASSWORD STORAGE.

    It's called "key strengthening" or "key stretching"; the idea is to add computational complexity to your password hashing. Although the OP gets it all wrong, here's pseudo code of what you would do:

    string hash_password(password, salt) {
      hash = password;
      for (i = 0; i < 100000; ++i) {
        hash = sha1(hash + salt);
      }
      return hash;
    }


    Then storing the salt and hash in the database. Also, the loop count could be stored as well, which means the number can be increased in the future (old hashes will use whatever loop count they are stored with).



  • Ah, right, that makes sense.

    (Although I would never use bcrypt because *shudder* php...)



  • @morbiuswilters said:

    Other WTFs:

    • Using HMAC for password hashing. WTF?
    On the bright side, at least an attacker can't use standard rainbow tables.


  • @Sutherlands said:

    (Although I would never use bcrypt because shudder php...)

    What? bcrypt isn't specific to PHP. If you aren't using bcrypt or scrypt (or PBKDF2), you are doing password hashing wrong. Besides that, what do you dislike about PHP?



  • @pjt33 said:

    @morbiuswilters said:
    Other WTFs:

    • Using HMAC for password hashing. WTF?
    On the bright side, at least an attacker can't use standard rainbow tables.

    True. As far as roll-your-own password schemes go, it's probably in the top 20% of those I've seen, even including the inexplicable use of HMAC and the lack of iterations. I mean, at least he understood the need for iterations, the bug is just an implementation detail. Which is once again why you never implement your own cryptographic functions. Even if you get the theory right, there's a chance you'll fuck up the implementation. Also, I have no idea how many iterations this is using but I doubt it's enough.



  • @morbiuswilters said:

    @Sutherlands said:
    (Although I would never use bcrypt because shudder php...)
    What? bcrypt isn't specific to PHP. If you aren't using bcrypt or scrypt (or PBKDF2), you are doing password hashing wrong.
    Thought it was a library.  I see now that it's an algorithm.

    @morbiuswilters said:

    Besides that, what do you dislike about PHP?
    Horrible SOAP support.  Scripting.  Hard to read.  Also, PHP devs (IME) can't write maintainable code.



  • @Sutherlands said:

    Thought it was a library.  I see now that it's an algorithm.

    It's both, but the library is C.

    @Sutherlands said:

    Horrible SOAP support.

    Fair enough.

    @Sutherlands said:

    Scripting.

    I don't even know what this means.

    @Sutherlands said:

    Hard to read.

    WTF? The syntax is pretty standard C-like syntax, used by Java, C#, etc..

    @Sutherlands said:

    Also, PHP devs (IME) can't write maintainable code.

    Well, some do. That's expected with a ubiquitous, easy-to-learn language.



  • @morbiuswilters said:

    @Sutherlands said:
    Also, PHP devs (IME) can't write maintainable code.

    Well, some do. That's expected with a ubiquitous, easy-to-learn language.

     

    I would have thought Sutherlands has been on this site long enough that unmaintainable code is not exclusive to PHP. Considering the latest CodeSOD uses C♯ — using a feature PHP is often ridiculed for having (eval).



  • @morbiuswilters said:

    @Sutherlands said:
    Hard to read.

    WTF? The syntax is pretty standard C-like syntax, used by Java, C#, etc..

    It's fairly similar, but there are quite a few traps. The use of [code].[/code] for string concatenation and the details around [code]$[/code] (e.g. the difference between [code]$foo->bar[/code] and [code]$foo->$bar[/code]) can easily confuse someone whose only experience is Java/C#.



  • @Zemm said:

    I would have thought Sutherlands has been on this site long enough that unmaintainable code is not exclusive to PHP. Considering the latest CodeSOD uses C♯ — using a feature PHP is often ridiculed for having (eval).

     

    Its another case of don't blame the tool. Its always people that suck ass. In my experience people keep sucking ass because they don't want to admit where that bad taste in their mouth is really coming from. No no, its the programming language, not the fact that you write code by hammering a huge turd stuck between your teeth onto the keys...

     



  • @Sutherlands said:

    [Also, PHP devs (IME) can't write maintainable code.

    That's not a fault of PHP, that's a fault of the environment those devs work in - indicates lack of policy and proper training.

    I've seen pretty unmaintainable code in quite a number of languages - PHP included, I'll concede.



  • @erikal said:

    they don't want to admit where that bad taste in their mouth is really coming from
     

    I accidentally asparagus



  • I've used PHP a little, but not a lot.  It's not that it's a horrible language, mostly I just don't want to write in it.  And the language seems to make it easy to write poor quality code. 



  • @Sutherlands said:

    I've used PHP a little, but not a lot.  It's not that it's a horrible language, mostly I just don't want to write in it.  And the language seems to make it easy to write poor quality code. 
    Likewise.  It is just too easy of a language to do bad stuff in.  Not to mention there are more powerful languages out there now that can smoke php with fancy functionality.



  • @Anketam said:

    @Sutherlands said:

    I've used PHP a little, but not a lot.  It's not that it's a horrible language, mostly I just don't want to write in it.  And the language seems to make it easy to write poor quality code. 
    Likewise.  It is just too easy of a language to do bad stuff in.  Not to mention there are more powerful languages out there now that can smoke php with fancy functionality.

    How about we skip the 10 pages of people discussing strongly vs weakly typed languages again ?


    however...

    I'm a student and i'm currently making an android app that will use some form of auth against an wcf (webservice).

    How do i secure that connection ? I had the initial impression that i could just salt+hash the pass clientside, and check the salt+hash serverside (recalculate against the known hash+pass). This would however make me vunerable to someone simply recording the hash and resending it....

    Is there any textbook solution to this problem ?



    (it's for a tic tac toe game - so it's just for fun, but i'd like to know the solution)



  • @swayde said:

    @Anketam said:

    @Sutherlands said:

    I've used PHP a little, but not a lot.  It's not that it's a horrible language, mostly I just don't want to write in it.  And the language seems to make it easy to write poor quality code. 
    Likewise.  It is just too easy of a language to do bad stuff in.  Not to mention there are more powerful languages out there now that can smoke php with fancy functionality.

    How about we skip the 10 pages of people discussing strongly vs weakly typed languages again ?


    however...

    I'm a student and i'm currently making an android app that will use some form of auth against an wcf (webservice).

    How do i secure that connection ? I had the initial impression that i could just salt+hash the pass clientside, and check the salt+hash serverside (recalculate against the known hash+pass). This would however make me vunerable to someone simply recording the hash and resending it....

    Is there any textbook solution to this problem ?



    (it's for a tic tac toe game - so it's just for fun, but i'd like to know the solution)

     

    Install an SSL certificate on your web server and have the client app always call the web services using the HTTPS protocol.

     



  • @mott555 said:

    Install an SSL certificate on your web server and have the client app always call the web services using the HTTPS protocol.



    That leaves the problem of buying it cheaply, any recommendations ?

    rapid ssl seems quite cheap at 11-18 usd/yr...

    since i'm only using it for myself, isn't i possible to generate one myself ?



  • @Sutherlands said:

    What is the purpose of iterating a number of times, and what is supposed to change?
     

     

    It's really just a waste of CPU time (and energy), but gets promoted a lot by people who either don't understand the concept of linear vs. exponential growth, or just think they're entitled to use stupid passwords and that we all need to suffer from slow logins so nobody finds out their password is "hunter2" or something.

    Allowing longer/higher-entropy passwords increases the CPU cost per hash linearly (actually, since most common hash functions process input in 64-byte blocks with an 8-byte trailer, it doesn't increase at all until 56 bytes), but increases the average number of hash attempts for a brute-force attack to work exponentially. Minuscule server load, huge burden on attackers. A randomly chosen 20-character password will never be cracked before the sun burns out even if all the computers in the world were harnessed to attack it.

    Using a more expensive hash function increases the CPU cost per hash linearly but doesn't increase the number of hash attempts for a brute-force attack at all, so the server and the attacker are both hurt equally. It's a stupid game to play, because bad guys have huge amounts of computational power at their disposal. If you make your hash function take an hour to evaluate, which is completely intolerable for legitimate logins, how long will a dictionary password take to brute force? Just an hour - because the attacker probably owns a botnet with as many CPUs as there are words in the English language.

    Preventing a user account from getting broken into requires responsibilities from both the user and the site. The user needs to use a good password, the site needs to never expose it in plaintext. You cannot relieve the user of their part of the burden by making the hash function slow.



  • @swayde said:

    @mott555 said:
    Install an SSL certificate on your web server and have the client app always call the web services using the HTTPS protocol.



    That leaves the problem of buying it cheaply, any recommendations ?

    rapid ssl seems quite cheap at 11-18 usd/yr...

    since i'm only using it for myself, isn't i possible to generate one myself ?

    1. If only one app will ever talk to the server (your app -> your server), then yes you can use a self-signed cert for it. If you later want a web browser to access that domain, you'll need a cert the web browser recognizes. (Which is ~$300/year, or more if you need a wildcard cert.)

    2) Don't accept the first, super-terse answer here on the DailyWTF forums as the end-all, be-all solution to all your problems. In fact, assume every post here is full of lies.



  • @blakeyrat said:

    assume every post here is full of lies.

    And chicken, evil chicken



  • @blakeyrat said:

    Don't accept the first, super-terse answer here on the DailyWTF forums as the end-all, be-all solution to all your problems. In fact, assume every post here is full of lies.
     

    Actually blakey is wrong. You need to assume every single post here is 100% truthful.

     



  • @mott555 said:

    @blakeyrat said:
    Don't accept the first, super-terse answer here on the DailyWTF forums as the end-all, be-all solution to all your problems. In fact, assume every post here is full of lies.
    Actually blakey is wrong. You need to assume every single post here is 100% truthful.


    This raises the question: Can chickens lie ?
    Also, thanks blakey.


  • @blakeyrat said:

    If you later want a web browser to access that domain, you'll need a cert the web browser recognizes. (Which is ~$300/year, or more if you need a wildcard cert.)
    Actually, domain-validated certificates are free (Startcom) or around $10/year (several providers), and Class 2 validated certs start at $50. EV (green bar) is somewhat more expensive. For in-application use, having a private CA is probably better than using a 3rd party one (assuming you know how to protect the key).
    @blakeyrat said:
    2) Don't accept the first, super-terse answer here on the DailyWTF forums as the end-all, be-all solution to all your problems. In fact, assume every post here is full of lies.
    Exactly. Isn't HMAC intended for just such validation?



  • @swayde said:

    I'm a student and i'm currently making an android app that will use some form of auth against an wcf (webservice).

    How do i secure that connection ? I had the initial impression that i could just salt+hash the pass clientside, and check the salt+hash serverside (recalculate against the known hash+pass). This would however make me vunerable to someone simply recording the hash and resending it....

    Is there any textbook solution to this problem ?

    SRP. http://srp.stanford.edu/



  • @pjt33 said:

    @swayde said:
    I'm a student and i'm currently making an android app that will use some form of auth against an wcf (webservice).

    How do i secure that connection ? I had the initial impression that i could just salt+hash the pass clientside, and check the salt+hash serverside (recalculate against the known hash+pass). This would however make me vunerable to someone simply recording the hash and resending it....

    Is there any textbook solution to this problem ?

    SRP. http://srp.stanford.edu/

    The correct answer is SSL. Secure password validation is virtually meaningless if the connection itself isn't encrypted. The problem is, I don't know if Android supports self-signed CAs or not.



  • @Goplat said:

    It's really just a waste of CPU time (and energy), but gets promoted a lot by people who either don't understand the concept of linear vs. exponential growth, or just think they're entitled to use stupid passwords and that we all need to suffer from slow logins so nobody finds out their password is "hunter2" or something.

    Allowing longer/higher-entropy passwords increases the CPU cost per hash linearly (actually, since most common hash functions process input in 64-byte blocks with an 8-byte trailer, it doesn't increase at all until 56 bytes), but increases the average number of hash attempts for a brute-force attack to work exponentially. Minuscule server load, huge burden on attackers. A randomly chosen 20-character password will never be cracked before the sun burns out even if all the computers in the world were harnessed to attack it.

    Using a more expensive hash function increases the CPU cost per hash linearly but doesn't increase the number of hash attempts for a brute-force attack at all, so the server and the attacker are both hurt equally. It's a stupid game to play, because bad guys have huge amounts of computational power at their disposal. If you make your hash function take an hour to evaluate, which is completely intolerable for legitimate logins, how long will a dictionary password take to brute force? Just an hour - because the attacker probably owns a botnet with as many CPUs as there are words in the English language.

    Preventing a user account from getting broken into requires responsibilities from both the user and the site. The user needs to use a good password, the site needs to never expose it in plaintext. You cannot relieve the user of their part of the burden by making the hash function slow.

    Wow, that has to be the dumbest fucking thing I've read all day. Congratulations.

    Hashing passwords protects against one thing: users who use the same password for multiple systems. The only reason we have to hash at all is because dipshits like you use the same password for everything because you don't know the first thing about security. By your logic we shouldn't be hashing passwords at all. Thankfully, every security professional thinks people like you are idiots.

    Increasing the computational complexity makes it harder for someone to brute-force the password. Yes, it can be done in parallel, but the idea is to increase the cost. To expand on your logic, we shouldn't use strong encryption since it can just be cracked more quickly in parallel. Obviously that is retarded.

    Are you seriously complaining about slow logins? Decent password hashing takes, at most, a second. Are you really this fucking stupid?



  • @morbiuswilters said:

    The correct answer is SSL. Secure password validation is virtually meaningless if the connection itself isn't encrypted. The problem is, I don't know if Android supports self-signed CAs or not.

    I believe that it's possible, but it depends on the app, just like "regular" browsers support it differently.



  • @morbiuswilters said:

    Hashing passwords protects against one thing: users who use the same password for multiple systems. The only reason we have to hash at all is because dipshits like you use the same password for everything because you don't know the first thing about security.
    If someone is using the same password for everything, they're screwed no matter what; somewhere it's going to get compromised in plaintext. I sure am not going to trust random internet forums with the password to my bank account. The benefit of hashing is that if a site's user database is compromised, users' accounts [i]on that site[/i] can't get broken into. That's what it's good for and that's [i]all[/i] it's good for.

    Increasing the computational complexity makes it harder for someone to brute-force the password. Yes, it can be done in parallel, but the idea is to increase the cost. To expand on your logic, we shouldn't use strong encryption since it can just be cracked more quickly in parallel. Obviously that is retarded.
    And you've just proven you don't understand the fundamental principle of modern cryptography: making the computational complexity exponential for the attacker [i]without[/i] doing the same to yourself. Strong encryption is useful because, assuming no flaws in the algorithm, an n-bit key takes O(n) time to encrypt/decrypt something if you already know it, but O(2^n) time to crack by brute force.

    Are you seriously complaining about slow logins? Decent password hashing takes, at most, a second. Are you really this fucking stupid?
    You do know web servers usually have multiple users, don't you? 1 second can become pretty long when there are hundreds of logins waiting to be processed because some idiot thought a slow hash function was a good idea. All it needs to take is a microsecond. Think a fast hash function can't possibly be good enough? Here's the SHA-1 of my dailywtf password: 90c357d8830fac5461ace506269a98fe3906ba6f. Since SHA-1 is supposedly so easy to brute force, go ahead and crack it. (Hint: The password is 20 random characters.)

     



  • @morbiuswilters said:

    Besides that, what do you dislike about PHP?
     

    It uses those ugly perl-style $ sigils that give me eye cancer.



  • @morbiuswilters said:

    DO NOT DO THIS. NEVER ROLL YOUR OWN CRYPTO FUNCTIONS. USE bcrypt OR scrypt IF YOU NEED SECURE PASSWORD STORAGE.

    I went and did a bit of research. Turns out Windows Vista added a crypto library called "bcrypt".  But it doesn't appear to contain any way to actually perform bcrypt password hashing.  You have to obtain a "algorithm provider handle" that you pass into the hash function, and there's no Blowfish algorithm provider!  And on further checking, it looks like every actual C bcrypt implementation out there assumes a *nix system.  So I have to ask, how is one supposed to "just use bcrypt" if one is not a *nix developer?

     



  • @topspin said:

    @morbiuswilters said:

    Besides that, what do you dislike about PHP?
     

    It uses those ugly perl-style $ sigils that give me eye cancer.

    Heh.  Yeah, those are almost as ugly as C++'s colon::cancer issues.

     



  • @Mason Wheeler said:

    @morbiuswilters said:

    DO NOT DO THIS. NEVER ROLL YOUR OWN CRYPTO FUNCTIONS. USE bcrypt OR scrypt IF YOU NEED SECURE PASSWORD STORAGE.

    I went and did a bit of research. Turns out Windows Vista added a crypto library called "bcrypt".  But it doesn't appear to contain any way to actually perform bcrypt password hashing.  You have to obtain a "algorithm provider handle" that you pass into the hash function, and there's no Blowfish algorithm provider!  And on further checking, it looks like every actual C bcrypt implementation out there assumes a *nix system.  So I have to ask, how is one supposed to "just use bcrypt" if one is not a *nix developer?

     


    try code.google.com/p/bcryptnet/ ?
    took me all of 2 sec of google... they even compiled the binaries for you!


  • @Goplat said:

    If someone is using the same password for everything, they're screwed no matter what; somewhere it's going to get compromised in plaintext. I sure am not going to trust random internet forums with the password to my bank account. The benefit of hashing is that if a site's user database is compromised, users' accounts on that site can't get broken into. That's what it's good for and that's all it's good for.

    You are so clueless it's painful. Password hashing would protect against the case where a site's user database is compromised but apparently nothing else is. However, that's not a very likely scenario; if the password database has been compromised, then you have to assume everything else has been as well. Seriously, do you think an attacker with access to the database is like "Oh, goody, now that I have the passwords I can go and login through the UI!" But even if that were the only case that hashing is supposed to protect against, then it is still worthwhile to make the expense of guessing hashes higher.

    @Goplat said:

    You do know web servers usually have multiple users, don't you? 1 second can become pretty long when there are hundreds of logins waiting to be processed because some idiot thought a slow hash function was a good idea. All it needs to take is a microsecond. Think a fast hash function can't possibly be good enough? Here's the SHA-1 of my dailywtf password: 90c357d8830fac5461ace506269a98fe3906ba6f. Since SHA-1 is supposedly so easy to brute force, go ahead and crack it. (Hint: The password is 20 random characters.)

    Sigh. So let me get this straight:

    • You are incapable of understanding that security is an issue of making exploitation too costly for an attacker. It's a constantly-evolving field that must change to adapt to advances in technology. Naive password-hashing algorithms are far too cheap to exploit which provides less protection, especially for shorter, less-random passwords.
    • You apparently don't realize that logins occur infrequently compared to other actions and that increasing computational complexity of the login is an extremely small cost overall.
    • You are too fucking stupid to realize that nobody said it was easy to brute-force a random, 20-character SHA-1 hash and that the entire point of increasing the expense is to make it harder to brute-force shorter, less-random passwords.
    • You know more than every other security professional in the world. Clearly they are wrong and some dipshit on an Internet forum is right, if only they'd listen to him.


    Really, it's clear you are out of your depth here. This isn't up for debate. You are spreading provable falsehoods.



  • @morbiuswilters said:

    Seriously, do you think an attacker with access to the database is like "Oh, goody, now that I have the passwords I can go and login through the UI!" But even if that were the only case that hashing is supposed to protect against, then it is still worthwhile to make the expense of guessing hashes higher.

    Yes. Yes I do. Maybe not the UI of the piddling forum. But there's a good chance that a lot of those will match email passwords, and maybe even banks. I don't claim to understand security or cryptography, but I can see the value in password / username / email combinations.



  • @swayde said:

    try code.google.com/p/bcryptnet/ ?

    took me all of 2 sec of google... they even compiled the binaries for you!

     

    I am also not a .NET developer.  Though I might be able to translate that if the C# isn't too horrible...

     



  • @boomzilla said:

    @morbiuswilters said:
    Seriously, do you think an attacker with access to the database is like "Oh, goody, now that I have the passwords I can go and login through the UI!" But even if that were the only case that hashing is supposed to protect against, then it is still worthwhile to make the expense of guessing hashes higher.

    Yes. Yes I do. Maybe not the UI of the piddling forum. But there's a good chance that a lot of those will match email passwords, and maybe even banks. I don't claim to understand security or cryptography, but I can see the value in password / username / email combinations.

    Which was my point: the primary objective of password hashing is to protect access to external systems where the same password is used, not to protect against usage in the already-exposed system.



  • @morbiuswilters said:

    You are so clueless it's painful. Password
    hashing would protect against the case where a site's user database is
    compromised but apparently nothing else is. However, that's not a very
    likely scenario; if the password database has been compromised, then you
    have to assume everything else has been as well.
    Which means the
    web server that handles logins has been compromised, which means the
    attacker is seeing passwords in the clear anyway. If this were true, it
    would be an argument that hashing at all is futile. (It's not true, though - SQL injection attacks, for example, rarely compromise the web server.)

    logins occur infrequently compared to other actions and that increasing
    computational complexity of the login is an extremely small cost
    overall.
    Even if people rarely log in to a site, someone can easily make login attempts occur as frequently as they want. Congratulations, your attempt to protect bad passwords makes your site a cinch to DoS.

    [...more insults, complete failure to put money where mouth is, lame attempt at appealing to authority without even citing any names]
    Since you admit you can't crack my password, obviously SHA-1 is sufficient protection if the user actually cares. And if they don't care about their own account, no reason I should either.

     



  • @Goplat said:

    @morbiuswilters said:
    You are so clueless it's painful. Password hashing would protect against the case where a site's user database is
    compromised but apparently nothing else is. However, that's not a very likely scenario; if the password database has been compromised, then you have to assume everything else has been as well.
    Which means the web server that handles logins has been compromised, which means the attacker is seeing passwords in the clear anyway. If this were true, it would be an argument that hashing at all is futile.

    You're forgetting to factor in 'dwell time'.  If your server gets cracked, and you let the attacker stay there for months, then, sure.

    However, if you're sophisticated enough to detect and expel the cracker in a reasonable time-frame - say a few hours - the cracker has time to make off with your password database, but doesn't have time to get all of the plaintext passwords from the users, because only a small portion of your users logged in during that time.

    So, if your passwords are plain text, your users are SOL.  If they're crypted or MD5 hashed, your users are SOL.  If they're SHA1 hashed, 98+% of your users are SOL.  If they're salted SHA512 hashed, then maybe 5% of your users are SOL - and mostly that's the ones that logged in during the cracker's dwell.

    @Goplat said:

    @morbiuswilters said:
    logins occur infrequently compared to other actions and that increasing
    computational complexity of the login is an extremely small cost overall.

    Even if people rarely log in to a site, someone can easily make login attempts occur as frequently as they want. Congratulations, your attempt to protect bad passwords makes your site a cinch to DoS.

    Sizing your site is something you do after you've developed your code (as well as before - capacity planning happens a whole bunch of times, because stuff changes).  Note that you also do some capacity planning while determining your algorithm, and it's a whole bunch of trade-offs.  But you should also spend a certain amount on DoS protection.  For example, if a particular IP address crosses a certain threshold on bad login attempts (as a portion of overall login attempts and total number per second), the firewall kicks in and blocks that IP address.  A DDoS still has an impact, but it takes a fairly large number of servers to sustain that impact for an extended period of time.  And, oh, that's a commercial service; kind of an HTTP version of an email RBL, and a lot of companies use it, so much of the various zombie networks are already blocked.  Yes, there are products out there that do this.  Also, if you care about your website, you really need something like this, because even if your server is just serving unencrypted static text files, if it's on the Internet, either it or your pipe can be overwhelmed.  The question is how much it'll cost your opposition.  With good defenses, that cost can be maximized much more than simply using efficient coding practices.

    @Goplat said:

    Since you admit you can't crack my password, obviously SHA-1 is sufficient protection if the user actually cares.

    A white-hat who is not in your employ not bothering to crack a password for you does not prove or disprove your hash's strength.  Note that, since you've published it, in a few years, Google will probably have the answer, without them even trying - they'll just pick it off some website where someone reports it.

    (Note: I've argued with Morbs on this subject, but I think my position is much closer to Morbs' than yours.  SHA512 is standard and easy.  It's very distinct from SHA1, so even if your code *doesn't* already support using multiple algorithms, it can still easily see whether the stored password is SHA1 or SHA512.  One still needs to code for it, but it's trivial code.  Even if SHA1 is secure now, it's old enough it's past time to move on.  In fact, I felt the need to move previously, to SHA256.  However, since you didn't do that before, doing it now would be silly.  And if your vendor doesn't support anything newer than SHA160 (aka SHA1), you should probably look at getting a new vendor, because it's been a really long time since that was best practice.)



  • @morbiuswilters said:

    @pjt33 said:
    @swayde said:
    I'm a student and i'm currently making an android app that will use some form of auth against an wcf (webservice).

    How do i secure that connection ? I had the initial impression that i could just salt+hash the pass clientside, and check the salt+hash serverside (recalculate against the known hash+pass). This would however make me vunerable to someone simply recording the hash and resending it....

    Is there any textbook solution to this problem ?

    SRP. http://srp.stanford.edu/

    The correct answer is SSL. Secure password validation is virtually meaningless if the connection itself isn't encrypted. The problem is, I don't know if Android supports self-signed CAs or not.

    SRP is actually more than a remote password verification: it remotely verifies a password while setting up a session key.

    @morbiuswilters said:

    Hashing passwords protects against one thing: users who use the same password for multiple systems.

    No: it also protects against idiots who backup /etc/shadow and then lose the backup tape.



  • @Goplat said:

    @morbiuswilters said:

    However, that's not a very
    likely scenario; if the password database has been compromised, then you
    have to assume everything else has been as well.

    Which means the
    web server that handles logins has been compromised, which means the
    attacker is seeing passwords in the clear anyway.

    Are they?

    Losing my password database doesn't necessarily mean the server's been owned - just that the DB's been copied. I can understand making an assumption that the rest of the server's unclean, but I can't make the leap of logic from "someone's got our DB" to "the attacker can see your plain-text password".



  • @Goplat said:

    Which means the
    web server that handles logins has been compromised, which means the
    attacker is seeing passwords in the clear anyway. If this were true, it
    would be an argument that hashing at all is futile. (It's not true, though - SQL injection attacks, for example, rarely compromise the web server.)

    Nobody said anything about web servers being compromised. And if you are such a shitty developer that you are even worrying about SQL injection then I guess that explains why simple password security is beyond you. If someone is in a position to steal your password database (which is one of the most secure pieces of data in your database) then you have to assume they can make off with the rest of your data, too.

    @Goplat said:

    Even if people rarely log in to a site, someone can easily make login attempts occur as frequently as they want. Congratulations, your attempt to protect bad passwords makes your site a cinch to DoS.

    If you're too stupid to use application-level controls over login frequency then you deserve being DoSed. SSL also creates extra potential for being DoSed, but that doesn't mean you shouldn't use SSL.

    @Goplat said:

    Since you admit you can't crack my password, obviously SHA-1 is sufficient protection if the user actually cares. And if they don't care about their own account, no reason I should either.

    This is the response I was trying to prod you in to. It's obvious that you've never held a real job since your attitude is "Fuck the users, it's not my responsibility to implement security for them". Not only is this user-hostile attitude what I expect from a mouth-breathing, shit-for-brains developer such as yourself, it's clear you've never actually been responsible for security in a real application. See, users have access to data so if their account is compromised it affects more people than just them, and if I could have done something to prevent it I end up screwed. Here are some other things you can also dispense with, since it's not the developers' responsibility to do security correctly:

    • SSL: If they don't care about the security of their network connection, why should I?
    • Minimum password requirements: if they want their password to be an empty string, who am I to stop them?
    • CSRF: It's their fault for keeping your site open while browsing malicious sites in another tab.

    And why SHA-1? MD5 is faster, so by your logic anyone who uses SHA-1 is just wasting cycles and making themselves more vulnerable to DoS.



  • @tgape said:

    (Note: I've argued with Morbs on this subject, but I think my position is much closer to Morbs' than yours.  SHA512 is standard and easy.  It's very distinct from SHA1, so even if your code doesn't already support using multiple algorithms, it can still easily see whether the stored password is SHA1 or SHA512.  One still needs to code for it, but it's trivial code.  Even if SHA1 is secure now, it's old enough it's past time to move on.  In fact, I felt the need to move previously, to SHA256.  However, since you didn't do that before, doing it now would be silly.  And if your vendor doesn't support anything newer than SHA160 (aka SHA1), you should probably look at getting a new vendor, because it's been a really long time since that was best practice.)

    I still think SHA512 is too fast to be a good password hashing algo, but at least it's a step in the right direction. Of course, a lot of crypt libraries support bcrypt (in addition to MD5, SHA-1, SHA256, SHA512) and the type identifier is stored at the beginning of the hash. Also note that if you use crypt's MD5 ($1) you are almost certainly using the FreeBSD MD5 which does key stretching (although it doesn't do enough iterations to be good against modern hardware).

    I think the real test is numbers: a modern GPU can do 1 billion SHA-1 hashes per second. That means a randomly-generated, 8-character alphanumeric password (which most people would consider reasonably secure and is certainly better than 90% of passwords people use) will take 218340s (2.52d) to brute force. By comparison, the same computer could probably do 10 bcrypt hashes per-second, which means the same 8-character password would take 692351.9 years to crack.



  • @pjt33 said:

    SRP is actually more than a remote password verification: it remotely verifies a password while setting up a session key.

    I would still strongly advocate SSL. SRP doesn't stop someone from modifying the request in-transit (or snagging the session key and sending another request from their own location with the same session key) nor does it protect the confidentiality of the data transmitted nor does it guarantee the authenticity of the server you are connecting to.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.